Dockerコンテナの起動時にコマンドを実行する必要がある場合は、このチュートリアルが役立ちます。 DockerfileのENTRYPOINT
およびCMD
命令を使用して、起動時に必要な数のコマンドを実行できます。
このチュートリアルでは、ENTRYPOINT
およびCMD
命令を使用してDockerfileで起動コマンドを実行し、それらの違いを理解する方法について説明します。
前提条件
このチュートリアルは実際のデモンストレーションを行うため、以下の準備が整っていることを確認してください:
- A Windows 10 PC – Windows 10 v10.0.19042 was used in this tutorial.
- Docker Desktop – このチュートリアルではDocker Desktop v3.3.1を使用します。
Dockerfileの作成
Dockerコンテナの起動コマンドを実行する前に、まずDockerfileを作成する必要があります。 Dockerfileは、コンテナやDockerイメージをビルドするためのコマンドのリストを含むテキストドキュメントであり、Dockerイメージの作成方法を決定します。
1. まず、管理者としてPowerShellを開きます。
2. このチュートリアルで使用するDockerfileと関連するすべてのファイルを保存する新しいフォルダを作成し、そのディレクトリに移動します。このチュートリアルでは~/dockerが使用されます。
3. 以下のコマンドを使用して、Dockerfileという名前の空のテキストファイルを作成します。
または、LinuxまたはMac OSの場合は以下のコマンドを使用してDockerfileを作成することもできます。
4. 最後に、以下の内容をDockerfileに追加します。
これで、まもなくDockerfileが作成されます。
Dockerイメージのビルド
Dockerfileが作成されたので、Dockerイメージをビルドして、DockerfileのENTRYPOINTおよびCMD命令に書かれたコマンドを実行する必要があります。イメージをビルドするための一つの方法は、build
コマンドを使用することです。
~/dockerディレクトリにいる間、以下のコマンドを実行します。以下のコマンドは、現在の作業ディレクトリ(.
)を指定して、demoという名前のDockerイメージ(-t demo
)を~/dockerのDockerfileから作成します。

Dockerコンテナの実行
Dockerイメージをビルドした後、Dockerイメージを実行し、DockerfileのENTRYPOINTおよびCMD命令からコマンドを実行するためのコンテナが必要になります。
Dockerコンテナを実行するには、run
コマンドを呼び出して、Dockerイメージ(demo
)の上に書き込み可能なコンテナレイヤーを作成します。以下の例では、-it
パラメータを使用してコンテナに対話的に接続し、サンプルの出力を表示します。

Exec vs. Shellフォーム
Dockerfileで起動コマンドを実行する方法を見つけると、2つの異なる方法があることに気付くかもしれません。各メソッドはコマンドを呼び出しますが、やり方は少し異なります。
Dockerがコマンドを実行する際、直接exec
を呼び出すか、コンテナのシェル(Linuxでは/bin/sh -c
、Windowsではcmd /S /C
)を経由してshell
を呼び出すことができます。
exec
を使用して実行されるコマンドは、以下に示すように、命令の後に呼び出す実行可能ファイル、および1つ以上のコマンドライン引数が続きます。
一方、shell
フォームでコマンドを記述する場合、コマンドを角カッコで囲む必要はありません。
CMD
に引数を指定しない場合、Dockerは常にexecフォームでコマンドを実行します(例:CMD <command>
)。
初めて始める場合、これら2つのコマンド呼び出しの違いはあまり重要ではありませんが、より高度になると、それぞれの利点と欠点がすぐにわかるようになります。
スタートアップコマンドの実行
このチュートリアルでは、DockerfileのENTRYPOINT
とCMD命令内で起動コマンドを実行するいくつかの例を通して、具体的な手順を説明します。
1. 以前作成したDockerfileをお好きなテキストエディタで開きます。
2. 以下に示す例のDockerfile内容をコピーして、Dockerfileに貼り付けて保存します。
このDockerfileは、ubuntu:20.04
をベースイメージとして使用してレイヤーを作成しています。そして、exec
とshell
形式を使用して、DockerfileのCMD
とENTRYPOINT
命令にecho
コマンドとHello world
引数を指定するようDockerに指示しています。
3. ~/dockerディレクトリ内で、docker build
コマンドを実行し、新しいイメージをdemo
としてビルドします。以下のコマンドは、イメージをdemo
としてタグ付けし、カレントディレクトリ(.
)にあるDockerfileを参照します。タグ

4. さて、イメージを使用してコンテナを実行し、先ほど作成したDockerイメージをベースにしたDockerコンテナを実行します。すると、コンテナがCMD
命令で指定されたHello world
が表示されます。

Dockerfile内での変数の使用
時々、事前に正確なコマンドライン引数を知ることができないことがあります。コマンドに渡す必要のある引数はランタイム時にのみ公開されます。コマンドへの引数を静的に割り当てる代わりに、変数を使用してそれらの引数をキャプチャして渡すことができます。
Dockerfileの変数は、
shell
形式でのみ使用できます。Dockerは、exec
形式で呼び出されるコマンドに変数をサポートしていません。
好きなテキストエディタでDockerfileを開き、次の一連のコマンドで中身を置き換えて保存します。
今回は、環境変数を使用してDockerfileを作成し、ENV
を使用して表示されています。以下の例では、Dockerfileはname
という名前の環境変数を値friend
で定義しています。作成された後、この環境変数は$name
を介して参照されます。
DockerがこのDockerfileを基にコンテナを実行すると、echo
コマンドを呼び出し、Welcome, friend
という引数を渡します。
今度は、Dockerイメージを作成し、オプションでshellform
というタグ名を指定してコンテナを再実行します。Dockerはecho
コマンドを呼び出し、期待される出力を返します。

DockerfileのENTRYPOINTとCMD命令を組み合わせる
多くの場合、CMDまたはENTRYPOINT命令で起動コマンドを呼び出します。これらの方法を使用して、いくつでもコマンドを呼び出すことができます。ただし、両方の命令を使用して単一のコマンドを呼び出し、それに「追加」することもできます。
前の例を基にしたビルドを行うと、以下の例のようなDockerfileができます。このままでは、イメージを作成し、そのイメージからコンテナを実行すると、Dockerはecho
コマンドを呼び出してHello
を返します。
たとえば、echo
コマンドに別の引数を渡したい場合があるかもしれませんが、すぐには渡したくないかもしれません。その場合、CMD
命令をコマンドなしで呼び出すことができます。
ENTRYPOINT
命令に続くCMD
命令で実行するコマンドを指定すると、DockerはCMD
に渡された値を引数として解釈します。コマンドとしてではなく。
以下のように、コマンドではなく引数(world
)のみを指定するCMD
命令を追加してください。
指示を組み合わせる場合は、常にexec形式で記述する必要があります。これは、コンマで区切られた個別の値を指定する「配列のような」動作を持つためです。
イメージをビルドし、そのイメージからコンテナを実行すると、2行の出力(Hello
とworld
)ではなく、1行の出力のみが返されることがわかります。これは、単一のecho
コマンドの呼び出しを意味します。

結論
今では、 CMD
と ENTRYPOINT
のDockerfile命令を使用してDockerコンテナの起動コマンドを実行する方法について理解が深まったはずです。各命令は少し異なるが、同じタスクを達成でき、一緒に使用することも可能です。
CMD
よりも ENTRYPOINT
を使用して起動コマンドを実行する方が好ましいシナリオを思いつけますか?