DockerfileでのRUNとCMDの違い


293

CMDvsをいつ使用すればよいか混乱していますRUN。たとえば、bash / shellコマンド(つまりls -la)を実行するには、常に使用しますCMDか、または使用する状況はありますRUNか?これら2つの同様のDockerfileディレクティブに関するベストプラクティスを理解しようとしています。


回答:


425

RUNはイメージビルドステップであり、RUNコマンドがコンテナーイメージにコミットされた後のコンテナーの状態です。DockerfileにはRUN、イメージを構築するために互いに重ねる多くのステップがあります。

CMDは、ビルドされたイメージを起動したときにコンテナがデフォルトで実行するコマンドです。Dockerfileは最後にCMD定義されたもののみを使用します。でCMDコンテナを起動すると、をオーバーライドできますdocker run $image $other_command

ENTRYPOINTCMD、コンテナーがイメージを開始する方法にも密接に関連しており、これを変更できます。


15
RUN環境をセットアップするために必要なすべてのことを実行すると、(唯一の)CMDがコンテナーで実行されているプロセスを起動します。たとえば、nginxの場合は、CMD ["nginx", "-g", "daemon off;"]
github.com / nginxinc / docker

「DockerfileはCMDを1つしか持てません」-技術的には当てはまりませんが、事実上、1つを除いてすべて無視されます。GingerBeerの答えを見てください。
Colm Bhandal

「Dockerfileは定義された最後のCMDのみを使用します」?実際には、定義された最後のCMDは、イメージをコンテナーとして起動するときに使用されますよね?
ポールチョン

1
はい@paulcheung dockerfileの最後のコマンドはイメージに書き込まれ、ビルドされたイメージを起動したときにコンテナーがデフォルトで実行するコマンドです。
マット

126

RUN -Dockerイメージのビルド中にコマンドがトリガーされます。

CMD -作成したDockerイメージを起動するときにコマンドがトリガーされます。


67

私が見つかりました。この両者の違いを理解する記事は非常に役立ちます。

RUN -RUN命令を使用すると、アプリケーションとそれに必要なパッケージをインストールできます。現在の画像の上でコマンドを実行し、結果をコミットして新しいレイヤーを作成します。多くの場合、Dockerfileに複数のRUN命令があります。

CMD -CMD命令では、デフォルトのコマンドを設定できます。これは、コマンドを指定せずにコンテナーを実行した場合にのみ実行されます。Dockerコンテナーがコマンドで実行される場合、デフォルトのコマンドは無視されます。Dockerfileに複数のCMD命令がある場合、最後以外のすべての
CMD命令は無視されます。


13

RUN - Pythonのをインストールし、あなたのコンテナが、今のpythonは、そのイメージに焼き付けた
CMDお気に入りのスクリプトを実行し、Pythonのhello.py -


CMD -Pythonをインストールします。私のコンテナは、Pythonをイメージに焼き付けていませんか?
Carlos Fontes、2018年

RUNはpythonのイメージレイヤーを作成し、CMDは単にイメージを作成しないコマンドを実行します
Rohit Salecha

8

RUNコマンド:RUNコマンドは基本的に、イメージを構築するときにデフォルトのコマンドを実行します。また、次のステップのためにイメージの変更をコミットします。

新しいイメージの構築プロセスを支援するために、複数のRUNコマンドが存在する場合があります。

CMDコマンド:CMDコマンドは、新しいコンテナのデフォルトコマンドを設定するだけです。これはビルド時に実行されません。

Dockerファイルに複数のCMDコマンドがある場合、最後のコマンドを除いて、それらはすべて無視されます。このコマンドは何も実行しないため、デフォルトのコマンドを設定するだけです。


6

注:RUNとCMDを混同しないでください。RUNは実際にコマンドを実行し、結果をコミットします。CMDはビルド時に何も実行しませんが、イメージの目的のコマンドを指定します。

ドッカーファイルリファレンスから

https://docs.docker.com/engine/reference/builder/#cmd


4

RUN:多くすることができ、ビルドプロセスで使用されます(例:複数のライブラリのインストール)

CMD:あなただけの1、持つことができ、実行開始点を(例えば["npm", "start"]["node", "app.js"]


2

既存の回答は、この質問を見ている人が必要とするもののほとんどをカバーしています。したがって、CMDとRUNのニッチな領域をいくつか取り上げます。

CMD:重複は許可されますが無駄です

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にあり、そのイメージがすでにキャッシュされている場合、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

1

RUNCMDについては十分な回答がありました。ENTRYPOINTにいくつかの単語を追加したいだけです。CMD引数はコマンドライン引数で上書きできますが、ENTRYPOINT引数は常に使用されます。

この記事は良い情報源です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.