同じじゃないの?新旧じゃないの?
dockerfileには”CMD”と”ENTRYPOINT”があります。
ぶっちゃけどっちでも動いたから役割は同じだと思っていた。
でも、役割が違うのだ。
イメージとしては”ENTRYPOINT”にはコマンドを、”CMD”には引数を指定する。
Docker Hubのメジャーなイメージでは”ENTRYPOINT”に”docker-entrypoint.sh”等の名称でシェルスクリプトが指定されているだろう。
例えばMySQLであれば概ね以下のような処理がスクリプトに記述されている。
- CMDの最初の引数が”mysql”ならそのコマンドを実行する
- CMDの最初の引数がオプション文字(”–“)なら”mysql”にそのオプションを指定して実行する。
- CMDの最初の引数に”mysql”以外のコマンドを指定していればそのコマンドを実行する
- CMDの指定がなければデフォルトで”mysql”を実行する
だからこそ、CMDにオプションのみ記載していても”mysql”コマンドを指定しても、あるいは何も指定しなくてもDBとして起動してくれるわけだ!なんと便利な。
ただこの挙動を見せるにはいくつか条件がある。
- “ENTRYPOINT”で上記のようなシェルが指定されていること
- “CMD”と”ENTRYPOINT”がexec形式で記載されていること
“1.”についてはもう言うべきことはないだろう。問題は”2.”だ。
exec形式の他に”shell”形式というものがある。この指定の仕方によって少しずつ挙動が異なるようなのだ。詳細はこちらの表を参照してほしい。
# exec形式
ENTRYPOINT ["実行ファイル", "パラメータ1", "パラメータ2"]
# shell形式
ENTRYPOINT コマンド パラメータ1 パラメータ2