dockerfileのENTRYPOINTとCMD
dockerfileのENTRYPOINTとCMDは、どちらもコンテナで実行するプロセスを指定するInstructionだ。
それぞれ単独で利用することも、組み合わせて利用することもできる。
どのように違うのか、どのように組み合わせることができるのか見ていこう。
CMD
まずCMDから見てみよう。
記述例
以下にCMDの記述例を示す。
CMD [ "echo", "hi" ]
実行例1
下記のようにコンテナを実行するとコンテナは「hi」と表示して終了する。
$ docker run ubuntu hi $
実行例2
docker runでコマンドを指定するとCMDの内容を上書きする。
下記の例ではdocker runで指定した「echo bye」が実行されている。
$ docker run ubuntu echo bye bye $
ENTRYPOINT
次にENTRYPOINTを見てみよう。
記述例
以下にENTRYPOINTの記述例を示す。
ENTRYPOINT [ "echo", "hi" ]
実行例1
下記のようにコンテナを実行するとコンテナは「hi」と表示して終了する。
$ docker run ubuntu hi $
実行例2
CMDと異なりdocker runでコマンドを指定してもENTRYPOINTの内容は上書きされない。ENRYPOINTの内容に追加される。
下記の例ではENTRYPOINTで指定した「echo hi」とdocker runで指定した「echo bye」が結合された「echo hi echo bye」が実行されている。
$ docker run ubuntu echo bye hi echo bye $
実行例3
実行例2の動作を利用して以下のように、ENTRYPOINTで「echo」を、docker runで表示する文字列をそれぞれ指定することができる。
下記の例ではENTRYPOINTで指定した「echo」とdocker runで指定した「bye」が結合された「echo bye」が実行されている。
ENTRYPOINT [ "echo" ]
$ docker run ubuntu bye bye $
-entrypointオプション
ENTRYPOINTは基本的にdocker runから上書きできない。しかし--entrypointオプションを指定すれば上書きすることが可能。
Best Practice
- docker runから上書きできないENTRYPOINT
- docker runから上書きできるCMD
この2つを組み合わせて以下のようにすることができる。
定義
ENTRYPOINT [ "echo" ] CMD [ "hi" ]
実行例1
docker runでなにも指定しない場合は「hi」と表示される。
$ docker run ubuntu hi $
実行例2
docker runでコマンドを指定した場合、指定した文字列が表示される。
下記の例ではENTRYPOINTで指定した「echo」とdocker runで指定した「bye」が結合された「echo bye」が実行されている。
$ docker run ubuntu bye bye $
まとめ
以上のことをまとめるとENTRYPOINTとCMDのBest Practiceは以下の通りとなる。
- 絶対に実行したいプロセスをENTRYPOINTで指定する。
- デフォルト引数をCMDで指定する。
- デフォルト以外の引数をプロセスに渡したい場合はdocker runで指定する。
おまけ:Kubernetesからの連携
- ENTRYPOINTはKubernetes設定ファイルのspec/containers/commandで上書きする。
- CMDはKubernetes設定ファイルのspec/containers/argで上書きする。