Dockerfile ENTRYPOINTおよびCMD命令の使用

Dockerコンテナの起動時にコマンドを実行する必要がある場合は、このチュートリアルが役立ちます。 DockerfileENTRYPOINTおよび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が使用されます。

mkdir ~/docker
cd docker

3. 以下のコマンドを使用して、Dockerfileという名前の空のテキストファイルを作成します。

cd > Dockerfile

または、LinuxまたはMac OSの場合は以下のコマンドを使用してDockerfileを作成することもできます。

touch Dockerfile

4. 最後に、以下の内容をDockerfileに追加します。

FROM ubuntu:20.04

これで、まもなくDockerfileが作成されます。

Dockerイメージのビルド

Dockerfileが作成されたので、Dockerイメージをビルドして、DockerfileのENTRYPOINTおよびCMD命令に書かれたコマンドを実行する必要があります。イメージをビルドするための一つの方法は、buildコマンドを使用することです。

~/dockerディレクトリにいる間、以下のコマンドを実行します。以下のコマンドは、現在の作業ディレクトリ(.)を指定して、demoという名前のDockerイメージ(-t demo)を~/dockerのDockerfileから作成します。

docker build -t demo .
Building a Docker Image

Dockerコンテナの実行

Dockerイメージをビルドした後、Dockerイメージを実行し、DockerfileのENTRYPOINTおよびCMD命令からコマンドを実行するためのコンテナが必要になります。

Dockerコンテナを実行するには、runコマンドを呼び出して、Dockerイメージ(demo)の上に書き込み可能なコンテナレイヤーを作成します。以下の例では、-itパラメータを使用してコンテナに対話的に接続し、サンプルの出力を表示します。

docker run -it demo
Running a Docker Container

Exec vs. Shellフォーム

Dockerfileで起動コマンドを実行する方法を見つけると、2つの異なる方法があることに気付くかもしれません。各メソッドはコマンドを呼び出しますが、やり方は少し異なります。

Dockerがコマンドを実行する際、直接execを呼び出すか、コンテナのシェル(Linuxでは/bin/sh -c、Windowsではcmd /S /C)を経由してshellを呼び出すことができます。

execを使用して実行されるコマンドは、以下に示すように、命令の後に呼び出す実行可能ファイル、および1つ以上のコマンドライン引数が続きます。

ENTRYPOINT ["executables", "parameter1", "parameter2", ...]
CMD ["executables", "parameter1", "parameter2:, ...]

一方、shellフォームでコマンドを記述する場合、コマンドを角カッコで囲む必要はありません。

ENTRYPOINT <command> "parameter1"
CMD <command> "parameter1"

CMDに引数を指定しない場合、Dockerは常にexecフォームでコマンドを実行します(例:CMD <command>)。

初めて始める場合、これら2つのコマンド呼び出しの違いはあまり重要ではありませんが、より高度になると、それぞれの利点と欠点がすぐにわかるようになります。

スタートアップコマンドの実行

このチュートリアルでは、DockerfileのENTRYPOINTとCMD命令内で起動コマンドを実行するいくつかの例を通して、具体的な手順を説明します。

1. 以前作成したDockerfileをお好きなテキストエディタで開きます。

2. 以下に示す例のDockerfile内容をコピーして、Dockerfileに貼り付けて保存します。

このDockerfileは、ubuntu:20.04をベースイメージとして使用してレイヤーを作成しています。そして、execshell形式を使用して、DockerfileのCMDENTRYPOINT命令にechoコマンドとHello world引数を指定するようDockerに指示しています。

FROM ubuntu:20.04
# CMD命令
CMD ["echo", "Hello world"] # Exec Form
CMD echo "Hello world"      # Shell Form
# ENTRYPOINT命令
ENTRYPOINT ["echo", "Hello world"] # Exec Form
ENTRYPOINT echo "Hello world"      # Shell Form

3. ~/dockerディレクトリ内で、docker buildコマンドを実行し、新しいイメージをdemoとしてビルドします。以下のコマンドは、イメージをdemoとしてタグ付けし、カレントディレクトリ(.)にあるDockerfileを参照します。タグ

docker build -t demo .
Building a Docker image with docker build

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

docker run -it demo
Running a Docker container with docker run

Dockerfile内での変数の使用

時々、事前に正確なコマンドライン引数を知ることができないことがあります。コマンドに渡す必要のある引数はランタイム時にのみ公開されます。コマンドへの引数を静的に割り当てる代わりに、変数を使用してそれらの引数をキャプチャして渡すことができます。

Dockerfileの変数は、shell形式でのみ使用できます。Dockerは、exec形式で呼び出されるコマンドに変数をサポートしていません。

好きなテキストエディタでDockerfileを開き、次の一連のコマンドで中身を置き換えて保存します。

今回は、環境変数を使用してDockerfileを作成し、ENVを使用して表示されています。以下の例では、Dockerfileはnameという名前の環境変数を値friendで定義しています。作成された後、この環境変数は$nameを介して参照されます。

DockerがこのDockerfileを基にコンテナを実行すると、echoコマンドを呼び出し、Welcome, friendという引数を渡します。

FROM ubuntu:20.04
ENV name friend

CMD echo "Welcome, $name"
# または
## ENTRYPOINT echo "Welcome, $name"

今度は、Dockerイメージを作成し、オプションでshellformというタグ名を指定してコンテナを再実行します。Dockerはechoコマンドを呼び出し、期待される出力を返します。

Building a Docker Image (shellform) and Running a Docker Container

DockerfileのENTRYPOINTとCMD命令を組み合わせる

多くの場合、CMDまたはENTRYPOINT命令で起動コマンドを呼び出します。これらの方法を使用して、いくつでもコマンドを呼び出すことができます。ただし、両方の命令を使用して単一のコマンドを呼び出し、それに「追加」することもできます。

前の例を基にしたビルドを行うと、以下の例のようなDockerfileができます。このままでは、イメージを作成し、そのイメージからコンテナを実行すると、Dockerはechoコマンドを呼び出してHelloを返します。

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]

たとえば、echoコマンドに別の引数を渡したい場合があるかもしれませんが、すぐには渡したくないかもしれません。その場合、CMD命令をコマンドなしで呼び出すことができます。

ENTRYPOINT命令に続くCMD命令で実行するコマンドを指定すると、DockerはCMDに渡された値を引数として解釈します。コマンドとしてではなく。

以下のように、コマンドではなく引数(world)のみを指定するCMD命令を追加してください。

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
CMD ["world"]

指示を組み合わせる場合は、常にexec形式で記述する必要があります。これは、コンマで区切られた個別の値を指定する「配列のような」動作を持つためです。

イメージをビルドし、そのイメージからコンテナを実行すると、2行の出力(Helloworld)ではなく、1行の出力のみが返されることがわかります。これは、単一のechoコマンドの呼び出しを意味します。

Building a Docker Image (demo3) and Running a Docker Container

結論

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

CMD よりも ENTRYPOINT を使用して起動コマンドを実行する方が好ましいシナリオを思いつけますか?

Source:
https://adamtheautomator.com/dockerfile-entrypoint/