CMD
およびENTRYPOINT
命令は、よく混同される2つのDockerfile
ディレクティブ。どちらも、コンテナの起動時に実行されるコマンドを決定する役割があります。
CMD
およびENTRYPOINT
各画像内で個別に上書きできます。これらのディレクティブを効果的に使用すると、提供するコマンドの長さが短くなり、コンテナーが使いやすくなります。
エントリポイントとは何ですか?
ENTRYPOINT
を見ていきます CMD
の前に処理されるため最初に 新しいコンテナを起動するとき。イメージのエントリポイントは、コンテナの起動時に実行されるプロセスを定義します。
Dockerは、エントリポイントをデフォルトで/bin/sh -c
に設定します 。これは、コンテナを起動したときにシェルセッションが終了することを意味します。多くのコンテナでは、デフォルトで別のプロセスを起動することがより望ましいです。ヘッドレスサービスでワークロードをすぐに開始する必要があります。
ENTRYPOINT
の設定 Dockerfile
のディレクティブ コンテナの起動時に特定のコマンドを実行するようにDockerに指示します。デフォルトのシェルセッションではなく、フォアグラウンドプロセスになります。
ENTRYPOINT ["date"]
このDockerfile
で作成されたコンテナ date
を実行します 指図。 date
として は長続きする前景プロセスではないため、コンテナはすぐに終了します。
エントリポイントは、実行可能なバイナリまたはスクリプトである必要があります。無効なエントリポイントを指定すると、コンテナは起動しません。カスタムスクリプトを使用している場合は、実行可能ビットが設定されていることを確認してください。 chmod +x my-script.sh
を使用して実行権限を追加できます 。
コマンドの追加(CMD)
CMD
指示は誤称のようなものです。 ENTRYPOINT
で定義されたコマンドのデフォルトの引数を提供します 。
ENTRYPOINT ["date"] CMD ["+%A"]
この例では、コンテナでdate +%A
が実行されます。 。 +%A
date
への引数 現在の曜日を表示します(例:Monday
。
CMD
オーバーライドされるように設計されています。 docker run
個々のコンテナインスタンスに別のコマンドを指定できます:
docker run my-image +%B
デフォルトのCMD
+%B
で上書きされます 、コンテナに現在の月の名前を表示させます。これは、画像のエントリポイントがそのまま残るために機能します。 CMD
常にENTRYPOINT
に追加されます 、したがって、最後のコマンドはdate +%B
になります 。
ENTRYPOINT
を使用する必要があります コンテナのプライマリ実行可能ファイルを定義します。 CMD
を使用する その実行可能ファイルのデフォルト引数を定義します。コンテナが異なる引数で実行されると、オーバーライドされます。
カスタムエントリポイントを使用して、Dockerにイメージを開始させることができます。 --entrypoint
を渡します docker run
へのフラグ :
docker run --entrypoint /bin/sh my-image
コンテナのイメージで定義されたエントリポイントは無視され、指定したコマンドが優先されます。この例では、date
の代わりにシェルセッションが開始されます コマンド。
エントリポイントのオーバーライドはまれにしか発生しません。画像の作者の意図に反する可能性があります。ただし、カスタムエントリポイントの設定は、特にデバッグ時に役立つ場合があります。コンテナの誤動作が発生した場合、そのエントリポイントを上書きすると、他の方法では取得できないシェルアクセスが許可される可能性があります。
どちらを使用しますか?
画像の作成者の場合は、ENTRYPOINT
を使用する必要があります コンテナの実行内容を定義するとき。デフォルトの引数を提供したいが、ユーザーがそれらをオーバーライドすることを期待する場合は、CMD
を含めます
画像ユーザーは、通常、CMD
のオーバーライドに固執することができます 。 docker run
コマンドオーバーライドを透過的にサポートします。画像名の後に指定された引数は、CMD
として解釈されます。 コンテナの文字列。
エントリポイントモード:シェルまたはExec
Dockerは、実際には2つの異なる形式のENTRYPOINT
をサポートしています。 :execモードとシェルモード。 Execモードは、配列構造を使用してパラメーターを指定することを特徴としています。シェルモードでは、コマンドは1つの文字列として指定されます。
# exec mode ENTRYPOINT ["binary", "--param", "--another-param"] # shell mode ENTRYPOINT binary --param --another-param
シェルモードを使用すると、バイナリが/bin/sh -c
のサブプロセスとして実行されます。 。これにより、シェルによって定義された環境変数へのエントリポイントアクセスが可能になります。
ただし、シェルモードにはトレードオフがあります。 CMD
は使用できません そのため、ユーザーはオーバーライドを発行できなくなります。 docker run
に与えられた引数 無視されます。コンテナは常にエントリポイントをそのまま使用します。
バイナリはシェル内で実行されるため、docker stop
などのDockerライフサイクルコマンド 不規則に動作するか、まったく動作しない可能性があります。 Dockerはシェルに信号を送ります 内のプロセスの代わりに停止します。 exec
を使用してプロセスを起動できます これを避けるために。
ENTRYPOINT exec binary --param --another-param
Dockerのエントリポイントアプローチのメリット
エントリポイントを引数から分離すると、コンテナの複雑さを隠すのに役立ちます。これは、CLIプログラムをカプセル化するユーティリティコンテナを作成する場合に最も役立ちます。
CLIのバイナリを画像のエントリポイントとして設定します。これにより、ユーザーは各コマンドでバイナリ名を繰り返すことなく対話できます。
上記のDockerfile
をパッケージ化したかどうかを検討してください date:latest
として :
# default entrypoint (/bin/sh -c) docker run date:latest date +%A # with `date` as the entrypoint docker run date:latest +%A`
カスタムエントリポイントを設定すると、コマンドが短縮され、繰り返しが減ります。 date
を呼び出すことで、コンテナはより特殊化されます 自動的。これにより、ユーザーにとってより使いやすいインターフェースが作成されます。
DockerのENTRYPOINT
およびCMD
指示はしばしば混乱の原因になります。それらの命名は、それらの意図された目的を覆い隠します。
ENTRYPOINT
を使用する 新しいコンテナの起動時に実行される「コマンド」を設定します。 CMD
を使用してデフォルトの引数を定義できます 。 ENTRYPOINT
およびCMD
一緒に組み合わせて、コンテナの最終的なコマンド文字列を生成します。
docker run
を使用する場合 、DockerはイメージのデフォルトのCMD
を置き換えます 指定した引数を使用します。画像のエントリポイントを上書きする必要がある場合は、--entrypoint
を使用してください フラグ。