DockerfileのENTRYPOINTとCMDって何が違うの?

こんにちは、さるまりんです。

今回はDockerです。

Dockerfileを書いていると、ENTRYPOINT や CMD というものを見かけます。

どちらもコマンドを書いているように見えるので、

「何が違うんだろう?」

と思ったことがあります。

最初は、

「どちらか片方だけあればいいんじゃないの?」

と思っていました。

が、実はどうもそうではなさそうで。

今回は、実際に動かしながら、その違いを見ていきます。

このDockerfileを見てみましょう

まずは、こんなDockerfileを用意します。

FROM alpine

ENTRYPOINT ["echo"]

CMD ["こんにちは"]

まずは深く考えずに動かしてみましょう。

イメージを作ります。

docker build -t sample .

そして実行します。

docker run sample

すると、

こんにちは

と表示されます。

少しだけ変えてみます

今度は、実行するときに後ろへ文字を付けてみます。

docker run sample Docker

今度は、

Docker

と表示されます。

「あれ?」

と思いませんでしたか?

Dockerfileには、こんにちは と書いてあったはずです。

CMDは置き換えられます

実は、実行時に後ろへ書いた

Docker

が、Dockerfileの

CMD ["こんにちは"]

の代わりになっています。

つまり、CMD は、

「特に指定がなければ、これを使います」

というデフォルト値のような役割なんですね。

ENTRYPOINTは変わりません

一方で、今回ずっと変わっていないものがあります。

それが、

ENTRYPOINT ["echo"]

です。

実行するときに引数を変えても、echo というコマンド自体は変わっていません。

ENTRYPOINT があることで、

「echo を実行する」

という役割は変わりません。

変わるのは、echo に渡す文字だけなんですね。

つまり、ENTRYPOINT は、

このコンテナが何をするものなのか

を決めています。

CMD は、その仕事に渡す、

標準の引数

というイメージです。

役割で考えてみましょう

ここまで見ると、なんとなく役割が見えてきます。

今回のDockerfileなら、

仕事
↓
echo

これが ENTRYPOINT です。

そして、

標準で渡すもの
↓
こんにちは

これが CMD です。

だから、何も指定しなければ、

こんにちは

になります。

でも、実行するときに

docker run sample Docker

と書けば、標準の引数だけが

Docker

へ変わるんですね。

ほかのコンテナでも同じように考えられます

この考え方は、echo だけのものではありません。

例えば、Pythonを実行するコンテナなら、

ENTRYPOINT が python
CMD が実行するファイル

という形にもできます。

役割が分かると、いろいろなDockerfileも少し読みやすくなります。

今回のまとめ

今回は、ENTRYPOINT と CMD の違いを見てきました。

ENTRYPOINT は、

このコンテナが何をするのか。

CMD は、

その仕事に渡す標準の引数。

そう考えると、二つある理由がちょっと分かりやすくなりますよね。

この先は?

今回分かったのは、ENTRYPOINT と CMD の「役割」でした。

実は、書き方にも少し違いがあります。

また、実行するときに変更する方法もあります。

Dockerには、「なるほど」と思える仕組みがまだたくさんあります。

これからも一つずつ見ていきたいと思います。

読んでいただき、ありがとうございました。

それではまた!