プログラミング初心者がアーキテクトっぽく語る

見苦しい記事も多数あるとは思いますが訂正しつつブログと共に成長していければと思います

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で上書きする。