岡野です。
DockerFileの命令である CMD と ENTRYPOINT について書いてみたいと思います。
結論
- CMD と ENTRYPOINT は動作は似ているが、比較しない方が理解しやすいと思う。
- CMDはDockerFile実行時にデフォルトで実行したいコマンドを記載する。デフォルトなのでDockerFile実行時の引数をもって上書き可能。
- ENTRYPOINT はDockerFile実行時に必ず実行したいコマンドを記載する。docker runするときに --entrypoint で上書き可能。
CMD
とENTRYPOINT
は比較しない方がいいと思う理由
確かに動作は似ているが、初期の勉強段階で比較対象の命令として認識すると、どちらか選択する必要があるように思えてしまう。(少なくとも自分は)
CMDの動作
公式に以下の記載があります。
DockerfileではCMD命令を1つしか記述できません。 仮に複数のCMDを記述しても、最後のCMD命令しか処理されません。
では以下のDockerFileでイメージを作成し、実行してみます。
image生成
実行
実行時に引数を渡して CMD を上書く
echoコマンドごと上書きされたことがわかります。
ENTRYPOINT
の動作
公式に以下の記載があります。
docker run image に対するコマンドライン引数は、exec 形式の ENTRYPOINT の指定要素の後に付け加えられます。 ENTRYPOINT 命令は複数記述されていても、最後の命令しか処理されません。
では以下のDockerFileでイメージを作成し、実行してみます。
image生成
実行
実行時に引数を渡して ENTRYPOINT を上書きしようとする。
上書きしようとして渡した引数がすべて、ENTRYPOINTで指定したechoコマンドの引数になっていることがわかります。
CMD と ENTRYPOINT の併用①
mage生成
実行
CMDを上書きしようとする。
こちらもCMDを上書きしようとして渡した引数が、ENTRYPOINTで指定したechoコマンドの引数になっていることがわかります。
CMD と ENTRYPOINT の併用②
ENTRYPOINT とCMD の順番を変えて実施してみます。
mage生成
実行
CMDを上書きしようとする。
実行される順番がDockerFileの記載と逆になっているようです。
公式に以下の記載があります。
ENTRYPOINT の exec 形式は、デフォルト実行するコマンドおよび引数として、ほぼ変わることがないものを設定します。 そして CMD 命令の 2 つある書式のいずれでもよいので、変更が必要になりそうな内容を追加で設定します。
上記より、CMD と ENTRYPOINT が同時に記載された場合、実行される順番は自動的にENTRYPOINT → CMDになるのではと考えています。
最後に
頑固なENTRYPOINT、柔軟なCMDといったところでしょうか。