はじめに
Docker では、コンテナ起動時に実行するコマンドを CMD とENTRYPOINT で指定できます。
どちらも似た機能を持っていますが、使い方を間違えると思った通りに動作しないことがあります。
この記事では、それぞれの違いや使い分けのポイントを簡潔にまとめます。
書こうと思ったきっかけ
Dockerfile を書いているとき、CMD ["./app"] を指定したのにdocker run myapp ls で ls が実行されてしまい、思った動作と違って驚きました。
調べると、CMD は上書きされる仕様で、確実にコマンドを実行したいなら ENTRYPOINT を使うべきと分かりました。
この違いを整理しておけば、同じように迷うことが減ると思い、まとめることにしました。
CMD とは?
CMD は コンテナ起動時に実行するデフォルトのコマンド を指定するための Dockerfile の命令です。
ただし、docker run 実行時に別のコマンドを指定すると、CMD の内容は上書きされます。
使い方
Dockerfile で以下のように指定します。
CMD ["echo", "Hello, World!"]
動作の特徴
-
CMDで指定したコマンドは、デフォルトの実行コマンド となる。 -
docker run実行時にコマンドを指定すると、CMDの内容は上書きされる。
実行例
docker run myapp
# → "Hello, World!" が表示される
docker run myapp ls
# → "ls" が実行される(CMD の "echo Hello, World!" は上書きされる)
ENTRYPOINT とは?
ENTRYPOINT は コンテナ起動時に必ず実行するコマンド を指定するための Dockerfile の命令です。
docker run 実行時に別のコマンドを指定しても、ENTRYPOINT の後ろに引数として渡されるため、上書きされません。
使い方
Dockerfile で以下のように指定します。
ENTRYPOINT ["echo"]
動作の特徴
-
ENTRYPOINTで指定したコマンドは 強制的に実行される。 -
docker run実行時に指定したコマンドは、ENTRYPOINTの引数として渡される。
実行例
docker run myapp Hello, World!
# → "Hello, World!" が表示される(echo の引数として渡される)
docker run myapp ls
# → "ls" が実行される(echo ls)
CMD と ENTRYPOINT の違いまとめ
Docker では CMD と ENTRYPOINT の両方を使ってコンテナ起動時に実行するコマンドを指定できますが、それぞれの動作には違いがあります。
| 比較項目 | CMD | ENTRYPOINT |
|---|---|---|
| 主な用途 | デフォルトのコマンドや引数を指定 | 常に実行すべきコマンドを指定 |
ユーザーが docker run 時にコマンドを上書きできるか |
できる(例: docker run myapp bash → bash が実行される) |
できない(例: docker run myapp bash → bash は ENTRYPOINT の引数として渡される) |
| 動作の安定性 | 上書き可能なので、意図せず変わる可能性がある | 強制的に実行されるため、意図した動作を保証しやすい |
使い分けのポイント
-
CMDはデフォルトのコマンドを指定するが、上書き可能。 -
ENTRYPOINTは強制的にコマンドを実行し、意図した動作を保証しやすい。 -
確実に実行すべきコマンドがある場合は
ENTRYPOINTを使うのが適切。
まとめ
最後までお読みいただき、ありがとうございました。Dockerコンテナの起動コマンド「CMD」と「ENTRYPOINT」の違いについて、理解が深まったなら嬉しいです。
今後も、このような基礎的な内容を分かりやすく整理し、丁寧にまとめていこうと思います。