回答:
RUNはイメージビルドステップであり、RUN
コマンドがコンテナーイメージにコミットされた後のコンテナーの状態です。DockerfileにはRUN
、イメージを構築するために互いに重ねる多くのステップがあります。
CMDは、ビルドされたイメージを起動したときにコンテナがデフォルトで実行するコマンドです。Dockerfileは最後にCMD
定義されたもののみを使用します。でCMD
コンテナを起動すると、をオーバーライドできますdocker run $image $other_command
。
ENTRYPOINTはCMD
、コンテナーがイメージを開始する方法にも密接に関連しており、これを変更できます。
RUN
環境をセットアップするために必要なすべてのことを実行すると、(唯一の)CMDがコンテナーで実行されているプロセスを起動します。たとえば、nginxの場合は、CMD ["nginx", "-g", "daemon off;"]
私が見つかりました。この両者の違いを理解する記事は非常に役立ちます。
RUN -RUN命令を使用すると、アプリケーションとそれに必要なパッケージをインストールできます。現在の画像の上でコマンドを実行し、結果をコミットして新しいレイヤーを作成します。多くの場合、Dockerfileに複数のRUN命令があります。
CMD -CMD命令では、デフォルトのコマンドを設定できます。これは、コマンドを指定せずにコンテナーを実行した場合にのみ実行されます。Dockerコンテナーがコマンドで実行される場合、デフォルトのコマンドは無視されます。Dockerfileに複数のCMD命令がある場合、最後以外のすべての
CMD命令は無視されます。
RUN - Pythonのをインストールし、あなたのコンテナが、今のpythonは、そのイメージに焼き付けた
CMDお気に入りのスクリプトを実行し、Pythonのhello.py -
注:RUNとCMDを混同しないでください。RUNは実際にコマンドを実行し、結果をコミットします。CMDはビルド時に何も実行しませんが、イメージの目的のコマンドを指定します。
ドッカーファイルリファレンスから
既存の回答は、この質問を見ている人が必要とするもののほとんどをカバーしています。したがって、CMDとRUNのニッチな領域をいくつか取り上げます。
GingerBeerは重要なポイントを示します。複数のCMDを入力してもエラーは発生しませんが、そうすることは無駄です。例を挙げて詳しく説明します。
FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"
これをイメージに組み込み、このイメージでコンテナーを実行すると、GingerBeerが述べるように、最後のCMDのみが考慮されます。したがって、そのコンテナの出力は次のようになります。
CMD 2の実行
私が考えるところ、「CMD」は構築されているイメージ全体に対して単一のグローバル変数を設定しているため、連続する「CMD」ステートメントは単にそのグローバル変数への以前の書き込みを上書きし、構築された最終的なイメージで勝利を書く最後のもの。Dockerfileは上から下に順番に実行されるため、一番下のCMDがこの最後の「書き込み」(比喩的に言えば)を取得するCMDであることがわかります。
RUNについて気を付けなければならないのは、副作用があっても純粋な関数として扱われるため、キャッシュされるということです。つまり、結果のイメージを変更しない副作用がRUNにあり、そのイメージがすでにキャッシュされている場合、RUNは再度実行されないため、後続のビルドで副作用が発生しません。たとえば、次のDockerfileを見てください。
FROM busybox
RUN echo "Just echo while you work"
初めて実行すると、さまざまな英数字IDで次のような出力が得られます。
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
上記でechoステートメントが実行されたことに注意してください。2回目に実行すると、キャッシュが使用され、ビルドの出力にエコーは表示されません。
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Using cache
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest