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

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

今回はDockerです。

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

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

「何が違うんだろう?」

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

最初は、

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

と思っていました。

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

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

この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を実行するコンテナなら、

ENTRYPOINTpython
CMD が実行するファイル

という形にもできます。

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

今回のまとめ

今回は、ENTRYPOINTCMD の違いを見てきました。

ENTRYPOINT は、

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

CMD は、

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

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

この先は?

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

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

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

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

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

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

それではまた!