docker run時にENTRYPOINTとCMDを上書きする方法!

Dockerを使っていると、次のような疑問を持つことはありませんか?

  • docker container runしたら、思っていたコマンドと違うものが実行された
  • ENTRYPOINTCMDを一時的に変えて実行したい
  • Dockerfileを書き換えずに、起動時の動作だけ変えたい

そんなときに非常に便利なのが、docker container run(docker run)時にENTRYPOINTCMDを上書きする方法です。

そもそもENTRYPOINTとCMDとは?

ENTRYPOINTCMDは、コンテナ起動時に実行されるコマンドを決める設定です。ただし、それぞれの役割は明確に分かれています。

ENTRYPOINTは「必ず実行されるメインのコマンド」です。

一方、CMDは、

  • ENTRYPOINTが定義されている場合は、ENTRYPOINTに渡されるデフォルト引数(args
  • ENTRYPOINTが定義されていない場合は、コンテナ起動時にデフォルトで実行されるコマンド

という 2つの役割を持つ設定になります。

例えば、Dockerfileが次のように書かれているとします。

ENTRYPOINT ["echo"]
CMD ["Hello, World!"]

この場合、コンテナ起動時に実行される実際のコマンドは以下のようになります。

echo Hello, World!

重要なのは、ENTRYPOINT + CMDが合体して1つのコマンドになるという点です。この前提を理解していないと、docker run時の上書き挙動が分かりにくくなります。

docker runでENTRYPOINTを上書きする方法

ENTRYPOINTを上書きする場合は、「--entrypointオプション」を使います。基本構文を以下に示します。

docker container run --entrypoint <新しいENTRYPOINT> イメージ名

例えば、DockerfileでENTRYPOINTechoが設定されているイメージを、lsに変えたい場合には、以下のコマンドを実行します。

docker container run --entrypoint ls sample-image

この場合、Dockerfileに設定されていたENTRYPOINT(echo)は無視され、代わりにlsが新しいENTRYPOINTとして使われます。なお、CMDが定義されている場合、CMDは新しいENTRYPOINTの引数(args)として渡されます。結果として実行されるコマンドは、以下のようになります。

ls "Hello, World!"

docker runでCMDを上書きする方法

CMDを上書きする場合は、イメージ名の後ろに「新しいCMD」を指定します。基本構文を以下に示します。

docker container run イメージ名 <新しいCMD配列の1要素目> <新しいCMD配列の2要素目> ...

例えば、DockerfileでCMDに["Hello, World!"]が設定されているイメージを、["Docker is fun!"]に変えたい場合には、以下のコマンドを実行します。

docker container run sample-image "Docker is fun!"

この場合、ENTRYPOINTはDockerfileに書かれているもの(echo)が使われ、CMD だけが["Docker is fun!"]に置き換わります。結果として実行されるコマンドは、以下のようになります。

echo Docker is fun!

docker runでENTRYPOINTとCMDを上書きする方法

ENTRYPOINTCMDの両方を上書きしたい場合は、「--entrypointオプション」と「新しいCMD」を組み合わせます。基本構文を以下に示します。

docker container run --entrypoint <新しいENTRYPOINT> イメージ名 <新しいCMD配列の1要素目> <新しいCMD配列の2要素目> ...

例えば、ENTRYPOINTprintf、CMDを["Hello %s\n", "Docker"]にしたい場合には、以下のコマンドを実行します。

docker container run --entrypoint printf sample-image "Hello %s\n" Docker

結果として実行されるコマンドは、以下のようになります。

printf "Hello %s\n" Docker

本記事のまとめ

この記事では『docker container run時にENTRYPOINTとCMDを上書きする方法』について説明しました。

DockerのENTRYPOINTCMDは、一見すると似ていますが、役割はまったく異なります。

docker container run時の挙動を正しく理解するためには、ENTRYPOINT + CMDが合体して1つのコマンドになる」という前提を押さえることが非常に重要です。

今回紹介した方法を使うと、docker container runの指定だけでコンテナの動きを変えられます。

  • --entrypointを使えばENTRYPOINTを一時的に差し替えられる
  • イメージ名の後ろにCMDを指定すればCMDだけを上書きできる

これらを使い分けることで、Dockerfileを修正しなくても、起動時のコマンドを自由に試せるようになります。「ちょっと別のコマンドで動かしてみたいとき」や「本番用イメージをそのまま使って中身を確認したいとき」に、非常に便利なテクニックです。

スポンサーリンク