Docker
Dockerfiles
サーチ…
前書き
Dockerfilesは、プログラムでDockerイメージを構築するために使用されるファイルです。 Dockerイメージを迅速かつ再現性よく作成できるため、共同作業に役立ちます。 Dockerファイルには、Dockerイメージを作成するための指示が含まれています。各命令は1行に記述され、 <INSTRUCTION><argument(s)>
の形式で与えられます。 Docker docker build
コマンドを使用してDockerイメージを構築するには、Dockerfilesを使用します。
備考
Dockerfilesの形式は次のとおりです。
# This is a comment
INSTRUCTION arguments
- コメントは
#
始まります。 - 指示は大文字のみです
- 基本イメージを指定するには、Dockerfileの最初の命令が
FROM
なければなりません
Dockerファイルを構築するとき、DockerクライアントはDockerデーモンに「構築コンテキスト」を送信します。ビルドコンテキストには、Dockerfileと同じディレクトリにあるすべてのファイルとフォルダが含まれます。 COPY
およびADD
操作では、このコンテキストのファイルしか使用できません。
一部のDockerファイルは、次のもので始まることがあります。
# escape=`
これは、Dockerパーサに`
\
代わりにエスケープ文字として使用するよう指示するために使用されます。これは主にWindows Dockerファイルに便利です。
HelloWorldドッカーファイル
最小のDockerfileは次のようになります。
FROM alpine
CMD ["echo", "Hello StackOverflow!"]
これにより、Dockerはアルパイン ( FROM
)に基づくイメージを構築し、コンテナーの最小限の配布を行い、結果イメージを実行するときに特定のコマンド( CMD
)を実行するよう指示します。
ビルドして実行する:
docker build -t hello .
docker run --rm hello
これは出力されます:
Hello StackOverflow!
ファイルのコピー
Dockerイメージのビルドコンテキストからファイルをコピーするには、 COPY
命令を使用します。
COPY localfile.txt containerfile.txt
ファイル名にスペースが含まれている場合は、代替構文を使用します。
COPY ["local file", "container file"]
COPY
コマンドはワイルドカードをサポートしています。たとえば、すべてのイメージをimages/
ディレクトリにコピーするために使用できます。
COPY *.jpg images/
注:この例では、 images/
が存在しない可能性があります。この場合、Dockerは自動的に作成します。
ポートを公開する
Dockerfileから公開されたポートを宣言するには、 EXPOSE
命令を使用します。
EXPOSE 8080 8082
Exposed portsの設定はDockerコマンドラインからオーバーライドできますが、Dockerファイルに明示的に設定することをお勧めします。
Dockerfilesのベストプラクティス
グループの一般的な操作
Dockerは画像をレイヤーの集合として構築します。各レイヤーは、ファイルが削除されたことをこのデータが示している場合でも、データを追加することができます。すべての命令が新しいレイヤーを作成します。例えば:
RUN apt-get -qq update
RUN apt-get -qq install some-package
欠点がいくつかあります:
- 2つのレイヤーが作成され、より大きなイメージが生成されます。
-
RUN
文で単独でapt-get update
を使用するとキャッシュの問題が発生し、apt-get install
命令が失敗することがあります。あとでパッケージを追加してapt-get install
変更した後、ドッカーが最初の命令と変更した命令を同じものとして解釈し、前の手順のキャッシュを再利用するとします。その結果、apt-get update
コマンドは、ビルド中にそのキャッシュされたバージョンが使用されるため、実行されません 。
代わりに、以下を使用します。
RUN apt-get -qq update && \
apt-get -qq install some-package
1つのレイヤーしか生成しないためです。
メンテナ
通常これはDockerfileの2行目です。誰が担当し、助けることができるのかを伝えます。
LABEL maintainer John Doe <[email protected]>
あなたがそれをスキップすると、あなたのイメージを壊すことはありません。しかし、それはあなたのユーザーのどちらにも役立ちません。
簡潔にする
Dockerファイルを短くしてください。複雑な設定が必要な場合は、専用のスクリプトを使用するか、ベースイメージを設定することを検討してください。
ユーザー指導
USER daemon
USER
命令は、イメージを実行し、いずれかの場合に使用するユーザー名またはUIDを設定RUN
、 CMD
とENTRYPOINT
で、それに続く命令Dockerfile
。
ワークディレクション
WORKDIR /path/to/workdir
WORKDIR
命令は、 WORKDIR
RUN
、 CMD
、 ENTRYPOINT
、 COPY
、およびADD
命令の作業ディレクトリを設定します。 WORKDIR
が存在しない場合は、後続のDockerfile
命令で使用されていなくても作成されます。
1つのDockerfile
で複数回使用できます。相対パスが指定されている場合は、前のWORKDIR
命令のパスからの相対パスになります。例えば:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
このDockerfile
最後のpwd
コマンドの出力は/a/b/c
です。
WORKDIR
命令は、 ENV
を使用して以前に設定した環境変数を解決できます。 Dockerfile
明示的に設定された環境変数のみを使用できます。例えば:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
このDockerfileの最終的なpwd
コマンドの出力は、 /path/$DIRNAME
音量指示
VOLUME ["/data"]
VOLUME
命令は、指定された名前のマウント・ポイントを作成し、ネイティブ・ホストまたは他のコンテナーから外部マウント・ボリュームを保持するものとしてマークします。値は、JSON配列、 VOLUME ["/var/log/"]
、またはVOLUME /var/log
やVOLUME /var/log /var/db
などの複数の引数を持つプレーンな文字列です。 Dockerクライアントを使用した詳細情報や例、マウント方法については、ボリュームを介した共有ディレクトリを参照してください。
docker run
コマンドは、新しく作成されたボリュームを、ベースイメージ内の指定された場所に存在するデータで初期化します。たとえば、次のDockerfileスニペットを考えてみましょう。
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
このDockerfileの結果、dockerが実行され、/ myvolに新しいマウントポイントが作成され、新しく作成されたボリュームにグリーティングファイルがコピーされます。
注:宣言後にボリューム内のデータを変更するビルドステップがあれば、その変更は破棄されます。
注意:リストはJSON配列として解析されます。つまり、一重引用符( ')ではなく、二重引用符( ")を使用する必要があります。
COPY命令
COPY
は2つの形式があります。
COPY <src>... <dest>
COPY ["<src>",... "<dest>"] (this form is required for paths containing whitespace)
COPY
命令は、 <src>
から新しいファイルまたはディレクトリをコピーし、パス<dest>
コンテナのファイルシステムに追加します。
複数の<src>
リソースを指定できますが、ビルド元のソースディレクトリ(ビルドのコンテキスト)に対して相対的でなければなりません。
各<src>
はワイルドカードが含まれ、一致はGoのfilepath.Match
を使用して行われます。一致ルール。例えば:
COPY hom* /mydir/ # adds all files starting with "hom"
COPY hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
<dest>
は、宛先コンテナ内でソースがコピーされる絶対パスまたはWORKDIR
基準とするパスです。
COPY test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/ # adds "test" to /absoluteDir/
すべての新しいファイルとディレクトリは、UIDとGIDが0で作成されます。
注:stdin( docker build - < somefile
)を使用してビルドする場合、ビルドコンテキストは存在しないため、 COPY
は使用できません。
COPY
は以下の規則に従います:
<src>
パスはビルドのコンテキスト内になければなりません。ドッカービルドの最初のステップは、コンテキストディレクトリ(およびサブディレクトリ)をドッカーデーモンに送信することなので、COPY
../something/ somethingをCOPY
できません。<src>
がディレクトリの場合、ファイルシステムのメタデータを含め、ディレクトリの内容全体がコピーされます。注:ディレクトリ自体はコピーされず、その内容だけがコピーされます。<src>
が他の種類のファイルである場合、そのメタデータと共に個別にコピーされます。この場合、<dest>
が末尾にスラッシュ/で終わると、ディレクトリとみなされ、<src>
内容は<dest>/base(<src>)
書き込まれます。複数の
<src>
リソースが直接指定されている場合、またはワイルドカードの使用のために指定されている場合、<dest>
はディレクトリでなければならず、スラッシュ/
終わる必要があります。<dest>
の末尾にスラッシュがない場合、通常のファイルとみなされ、<src>
内容は<dest>
書き込まれます。<dest>
が存在しない場合は、そのパスに存在しないすべてのディレクトリと共に作成されます。
ENVおよびARG命令
ENV
ENV <key> <value>
ENV <key>=<value> ...
ENV
命令は、環境変数<key>
を値に設定します。この値はすべての "子孫" Dockerfileコマンドの環境にあり、多くの場合でもインラインで置き換えることができます。
ENV
命令には2つの形式があります。最初の形式ENV <key> <value>
は、単一の変数を値に設定します。最初のスペースの後の文字列全体は、スペースや引用符などの文字を含む<value>
として扱われます。
第2の形式、 ENV <key>=<value> ...
は、一度に複数の変数を設定することを可能にします。 2番目のフォームは構文で等号(=)を使用していますが、最初のフォームではそうではありません。コマンドライン解析と同様に、引用符とバックスラッシュを使用して値にスペースを含めることができます。
例えば:
ENV myName="John Doe" myDog=Rex\ The\ Dog \
myCat=fluffy
そして
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy
最終コンテナで同じネット結果が得られますが、単一のキャッシュレイヤーを生成するため、最初のフォームが優先されます。
ENV
を使用して設定された環境変数は、コンテナが結果のイメージから実行されたときにも保持されます。 docker run --env <key>=<value>
inspectを使用して値を表示し、 docker run --env <key>=<value>
を使用して値を変更できdocker run --env <key>=<value>
。
ARG
設定を保持しない場合は、代わりにARG
使用してください。 ARG
は構築中にのみ環境を設定します。たとえば、
ENV DEBIAN_FRONTEND noninteractive
apt-get
ユーザは、 docker exec -it the-container bash
介して対話コンテキストでコンテナに入ったときに、Debianベースのイメージを混乱させる可能性があります。
代わりに、以下を使用します。
ARG DEBIAN_FRONTEND noninteractive
次のコマンドを使用するだけで、1つのコマンドに値を設定することもできます。
RUN <key>=<value> <command>
露出指示
EXPOSE <port> [<port>...]
EXPOSE
命令は、コンテナが実行時に指定されたネットワークポートをリッスンすることをDockerに通知します。 EXPOSE
は、コンテナのポートをホストからアクセス可能にしません。そのためには、ポート範囲を公開するには-p
フラグを使用するか、公開されているすべてのポートを公開するには-P
フラグを使用する必要があります。これらのフラグは、 docker run [OPTIONS] IMAGE [COMMAND][ARG...]
ポートをホストに公開するために使用されます。 1つのポート番号を公開し、別の番号で外部に公開することができます。
docker run -p 2500:80 <image name>
このコマンドは、<image>という名前のコンテナを作成し、コンテナのポート80をホストマシンのポート2500にバインドします。
ホスト・システムでポート・リダイレクションをセットアップするには、 -P
フラグの使用を参照してください。 Dockerネットワーク機能は、ネットワーク内のポートを公開せずにネットワークを作成することをサポートしています(詳細については、この機能の概要を参照してください)。
LABEL命令
LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL
命令は、画像にメタデータを追加します。 LABEL
はキーと値のペアです。 LABEL
値にスペースを含めるには、コマンドライン解析と同様に引用符とバックスラッシュを使用します。いくつかの使用例:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
イメージには複数のラベルを付けることができます。複数のラベルを指定するには、可能であればラベルを単一のLABEL
命令に結合することをお勧めします。各LABEL
命令は新しいレイヤーを作成し、多くのラベルを使用すると非効率的なイメージになる可能性があります。この例では、単一のイメージレイヤーが作成されます。
LABEL multi.label1="value1" multi.label2="value2" other="value3"
上記は次のように書くこともできます:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
ラベルは、 FROM
イメージのLABEL
を含めて加法的です。 Dockerが既に存在するラベル/キーに遭遇した場合、新しい値は同一のキーを持つ以前のラベルを上書きします。
イメージのラベルを表示するには、docker inspectコマンドを使用します。
"Labels": {
"com.example.vendor": "ACME Incorporated"
"com.example.label-with-value": "foo",
"version": "1.0",
"description": "This text illustrates that label-values can span multiple lines.",
"multi.label1": "value1",
"multi.label2": "value2",
"other": "value3"
},
CMD命令
CMD
命令には3つの形式があります。
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
Dockerfile
にはCMD
命令は1つしか存在できません。複数のCMD
をリストすると、最後のCMD
だけが有効になります。
CMD
の主な目的は、実行中のコンテナのデフォルトを提供することです。これらのデフォルトには実行可能ファイルを含めることができますが、実行ファイルを省略することもできます。この場合、 ENTRYPOINT
命令も指定する必要があります。
注: CMD
を使用してENTRYPOINT
命令のデフォルト引数を指定する場合は、 CMD
命令とENTRYPOINT
命令の両方をJSON配列形式で指定する必要があります。
注意:execフォームはJSON配列として解析されます。つまり、一重引用符( ')以外の単語を二重引用符( ")で囲む必要があります。
注:シェル形式とは異なり、exec形式ではコマンドシェルは呼び出されません。つまり、通常のシェル処理は行われません。たとえば、 CMD [ "echo", "$HOME" ]
は$HOME
変数置換を行いません。シェル処理を行う場合は、シェルフォームを使用するか、シェルを直接実行します( CMD [ "sh", "-c", "echo $HOME" ]
。
CMD
命令は、シェル形式またはEXEC形式で使用すると、イメージの実行時に実行されるコマンドを設定します。
CMD
シェル形式を使用すると、コマンドは/bin/sh -c
:
FROM ubuntu
CMD echo "This is a test." | wc -
シェルなしでコマンドを実行する場合は、コマンドをJSON配列として表現し、実行可能ファイルのフルパスを指定する必要があります。この配列形式は、 CMD
の好ましい形式です。追加のパラメータは、配列内の文字列として個別に表現する必要があります。
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
コンテナに毎回同じ実行可能ファイルを実行させる場合は、 CMD
と組み合わせてENTRYPOINT
を使用することを検討する必要があります。 ENTRYPOINT
参照してください。
ユーザーがドッカーの実行に引数を指定すると、 CMD
指定されたデフォルトを上書きします。
注意: RUN
とCMD
混同しないでください。 RUN
実際には画像構築時にコマンドを実行し、結果をコミットします。 CMD
はビルド時には何も実行しませんが、イメージに意図されたコマンドを指定します。
主催者の指示
MAINTAINER <name>
MAINTAINER
命令では、生成された画像のAuthorフィールドを設定できます。
MAINTAINER DIRECTIVEを使用しないでください
Official Docker Documentationによると、 MAINTAINER
命令は推奨されなくなりました。代わりに、 LABEL
命令を使用して、生成されたイメージの作成者を定義する必要があります。 LABEL
命令は柔軟性があり、メタデータの設定を可能にし、 docker inspect
コマンドで簡単に表示できます。
LABEL maintainer="[email protected]"
FROM命令
FROM <image>
または
FROM <image>:<tag>
または
FROM <image>@<digest>
FROM
命令は、その後の命令のためにベースイメージを設定します。そのため、有効なDockerファイルの最初の命令はFROM
なければなりません。イメージは任意の有効なイメージにすることができます。パブリック・リポジトリからイメージを取り出すことによって開始するのは特に簡単です。
FROM
はDockerfileの最初の非コメント命令でなければなりません。
複数の画像を作成するために、単一のDockerファイル内にFROM
を複数回表示することができます。各新しいFROM
コマンドの前に、コミットによって最後に出力されたイメージIDを書き留めるだけです。
タグまたはダイジェスト値はオプションです。どちらかを省略すると、ビルダーはデフォルトで最新のものとみなします。ビルダーは、タグ値と一致しない場合はエラーを戻します。
実行命令
RUN
は2つの形式があります:
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)
RUN
命令は、現在の画像の上に新しいレイヤーのコマンドを実行し、結果をコミットします。結果として得られたコミットされたイメージは、 Dockerfile
次のステップで使用されます。
レイヤー化されたRUN
命令と生成コミットは、Dockerのコアコンセプトに準拠しています。ここでは、コミットは安く、ソース管理と同様に画像の履歴の任意の点からコンテナを作成できます。
exec形式を使用すると、シェル文字列の混乱を避けることができ、指定されたシェル実行可能ファイルを含まないベースイメージを使用してRUN
コマンドを実行することができます。
シェルフォームのデフォルトのシェルは、 SHELL
コマンドを使用して変更できます。
シェル形式では、 \
(バックスラッシュ)を使用して、次の行に1つのRUN
命令を続けることができます。たとえば、次の2つの行を考えてみましょう。
RUN /bin/bash -c 'source $HOME/.bashrc ;\
echo $HOME'
これらは一緒に1行に相当します:
RUN /bin/bash -c 'source $HOME/.bashrc ; echo $HOME'
注: '/ bin / sh'以外の別のシェルを使用するには、目的のシェルを渡すexecフォームを使用します。たとえば、 RUN ["/bin/bash", "-c", "echo hello"]
注意:execフォームはJSON配列として解析されます。つまり、一重引用符( '
)以外の単語を二重引用符( “
)で囲む必要があります。
注:シェル形式とは異なり、exec形式ではコマンドシェルは呼び出されません。つまり、通常のシェル処理は行われません。たとえば、 RUN [ "echo", "$HOME" ]
は$HOME
変数置換を行いません。シェル処理を行う場合は、シェルフォームを使用するか、シェルを直接実行します( RUN [ "sh", "-c", "echo $HOME" ]
。
注意:JSON形式では、バックスラッシュをエスケープする必要があります。これは、バックスラッシュがパス区切り文字であるWindowsで特に重要です。以下の行は、有効なJSONではないためシェルフォームとして扱われ、予期しない方法で失敗します: RUN ["c:\windows\system32\tasklist.exe"]
この例の正しい構文は次のとおりですRUN ["c:\\windows\\system32\\tasklist.exe"]
RUN
命令のキャッシュは、次のビルド中に自動的に無効化されません。 RUN apt-get dist-upgrade -y
ような命令のキャッシュは、次のビルド中に再利用されます。 RUN
命令のキャッシュは、--no-cacheフラグを使用して無効にすることができます(例:docker build --no-cache)。
詳細については、Dockerfileベストプラクティスガイドを参照してください。
RUN
命令のキャッシュは、 ADD
命令によって無効にすることができます。詳細は以下を参照してください。
ONBUILD命令
ONBUILD [INSTRUCTION]
ONBUILD
命令は、イメージが別のビルドのベースとして使用されるときに、後で実行されるトリガ命令をイメージに追加する。トリガは、下流のDockerfileのFROM
命令の直後に挿入されたかのように、下流のビルドのコンテキストで実行されます。
どのビルド命令もトリガとして登録できます。
これは、アプリケーション構築環境やユーザー固有の構成でカスタマイズ可能なデーモンなど、他のイメージを構築するためのベースとして使用されるイメージを構築する場合に便利です。
たとえば、イメージが再利用可能なPythonアプリケーションビルダーである場合、特定のディレクトリにアプリケーションソースコードを追加する必要があります。そのあとでビルドスクリプトを呼び出す必要があります。アプリケーションのソースコードにまだアクセスしていないため、 ADD
とRUN
呼び出すことはできません。アプリケーションのビルドごとに異なります。アプリケーション開発者に、アプリケーションにコピー・ペーストするための定型的なDockerfileを提供するだけでも問題はありませんが、アプリケーション固有のコードと混同されるため、エラーが発生しやすく、更新が困難です。
解決方法は、 ONBUILD
を使用して、次のビルド段階で、後で実行するように進行命令を登録することです。
それはどのように動作するのです:
ONBUILD
命令をONBUILD
すると、ビルダーはトリガーをビルド中のイメージのメタデータに追加します。命令は現在のビルドに影響しません。
ビルドの最後に、すべてのトリガーのリストが、画像マニフェストのキーOnBuildの下に格納されます。彼らは、 docker inspect
コマンドで検査することができます。その後、 FROM
命令を使用して、イメージを新しいビルドのベースとして使用することができます。 FROM
命令の処理の一部として、ダウンストリーム・ビルダーはONBUILD
トリガーを検索し、登録されたのと同じ順序で実行します。いずれかのトリガが失敗すると、 FROM
命令が中止され、ビルドが失敗します。すべてのトリガーが成功すると、 FROM
命令は完了し、通常通りビルドが続行されます。
トリガーは、実行後に最終イメージからクリアされます。言い換えれば、それらは「グランド・チャイルド」ビルドによって継承されません。
たとえば、次のようなものを追加することができます。
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
警告: ONBUILD
ONBUILD
を使用してONBUILD
命令を連鎖さONBUILD
ことはできません。
警告: ONBUILD
命令は、 FROM
またはMAINTAINER
命令をトリガしません。
STOPSIGNAL命令
STOPSIGNAL signal
STOPSIGNAL
命令は、コンテナに送られて終了するシステムコール信号を設定します。このシグナルは、カーネルのsyscallテーブル内の位置(例えば9)に一致する有効な符号なしの番号、またはSIGAMEのような形式のシグナル名(例えばSIGKILL)です。
保健指導
HEALTHCHECK
命令には、次の2つの形式があります。
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
HEALTHCHECK
命令は、Dockerに、コンテナがまだ動作していることを確認するためのテスト方法を指示します。これにより、サーバプロセスがまだ実行中であっても、無限ループに陥り、新しい接続を処理できないWebサーバなどのケースを検出できます。
コンテナにヘルスチェックが指定されている場合、コンテナには通常の状態に加えて正常性ステータスがあります。このステータスは、最初は開始されています。ヘルスチェックが合格するたびに、健康状態になります(以前の状態に関係なく)。特定の回数の連続した失敗の後、それは不健全になります。
CMD
前に表示されるオプションは次のとおりです。
--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--retries=N (default: 3)
ヘルスチェックは、最初にコンテナが開始されてから数秒後に実行され、前のチェックが完了するたびに間隔秒後に実行されます。
チェックの1回の実行にタイムアウト秒を超えると、チェックは失敗したとみなされます。
コンテナが正常でないとみなされるために、ヘルスチェックの連続した失敗が再試行されます。
一つだけ存在できHEALTHCHECK
の命令Dockerfile
。 2つ以上をリストすると、最後のHEALTHCHECK
だけがHEALTHCHECK
になります。
CMD
キーワードの後のコマンドは、シェルコマンド( HEALTHCHECK CMD /bin/check-running
)またはexecアレイ(他のDockerfileコマンドと同様に、詳細はENTRYPOINT
を参照してください)。
コマンドの終了ステータスは、コンテナの正常性ステータスを示します。可能な値は次のとおりです。
-
0: success
- コンテナは健康で使用可能です -
1: unhealthy
- コンテナが正しく動作していない -
2: starting
- コンテナはまだ使用できる状態ではなく、正しく動作しています
コンテナがすでに「開始」状態から移動したときにプローブが2(「開始」)を返した場合、代わりに「不健全」として扱われます。
たとえば、Webサーバーが3秒以内にサイトのメインページを提供できるように5分ごとにチェックするには、次のようにします。
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
失敗したプローブをデバッグするのに役立つように、コマンドがstdoutまたはstderrに書き込む出力テキスト(UTF-8エンコード)は、正常性状態に格納され、 docker inspect
で照会できます。そのような出力は短く保たれるべきです(最初の4096バイトだけが現在格納されています)。
コンテナの正常性状態が変わると、新しい状態でhealth_status
イベントが生成されます。
Docker 1.12にHEALTHCHECK
機能が追加されました。
シェル命令
SHELL ["executable", "parameters"]
SHELL
命令では、シェル形式のコマンドに使用されるデフォルトのシェルをオーバーライドすることができます。 Linuxのデフォルトのシェルは["/bin/sh", "-c"]
、Windowsでは["cmd", "/S", "/C"]
です。 SHELL
命令は、DockerfileのJSON形式で記述する必要があります。
SHELL
命令は、Windows上で特に有用です。ここでは、一般的に使用され、全く異なる2つのネイティブシェルがあります:cmdとpowershell、shを含む代替シェルがあります。
SHELL
命令は複数回現れます。各SHELL
命令は、以前のすべて上書きされますSHELL
指示をし、すべての後続の命令に影響を与えます。例えば:
FROM windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello
SHELL
命令のシェル形式がDockerfileで使用されている場合( RUN
、 CMD
、 ENTRYPOINT
、次の命令はSHELL
命令の影響を受けます。
次の例は、Windows上で見つかった一般的なパターンであり、 SHELL
命令を使用して簡素化することができます。
...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
ドッカーによって呼び出されるコマンドは次のようになります。
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
これは2つの理由で非効率的である。まず、不要なcmd.exeコマンドプロセッサ(別名シェル)が呼び出されます。第2に、シェル形式の各RUN
命令は、余分なpowershellコマンドを前置するコマンドを必要とします。
これをより効率的にするために、2つのメカニズムの1つを使用することができます。 1つは、次のようなRUN
コマンドのJSON形式を使用することです。
...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...
JSONフォームは明白であり、不要なcmd.exeを使用しませんが、二重引用符とエスケープを使用すると、より詳細な冗長性が必要になります。別の仕組みは、 SHELL
命令とシェル形式を使用することです。特に、エスケープ・パーサー・ディレクティブと組み合わせると、Windowsユーザーにとってより自然な構文になります。
# escape=`
FROM windowsservercore
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'
その結果:
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 3.584 kB
Step 1 : FROM windowsservercore
---> 5bc36a335344
Step 2 : SHELL powershell -command
---> Running in 87d7a64c9751
---> 4327358436c1
Removing intermediate container 87d7a64c9751
Step 3 : RUN New-Item -ItemType Directory C:\Example
---> Running in 3e6ba16b8df9
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/2/2016 2:59 PM Example
---> 1f1dfdcec085
Removing intermediate container 3e6ba16b8df9
Step 4 : ADD Execute-MyCmdlet.ps1 c:\example\
---> 6770b4c17f29
Removing intermediate container b139e34291dc
Step 5 : RUN c:\example\Execute-MyCmdlet -sample 'hello world'
---> Running in abdcf50dfd1f
Hello from Execute-MyCmdlet.ps1 - passed hello world
---> ba0e25255fda
Removing intermediate container abdcf50dfd1f
Successfully built ba0e25255fda
PS E:\docker\build\shell>
SHELL
命令は、シェルの動作方法を変更するためにも使用できます。たとえば、WindowsでSHELL cmd /S /C /V:ON|OFF
を使用すると、遅延環境変数拡張セマンティクスを変更できます。
SHELL
命令は、zsh、csh、tcshなどの代替シェルが必要な場合はLinuxでも使用できます。
SHELL
機能がDocker 1.12に追加されました。
Debian / Ubuntuパッケージのインストール
1回の実行コマンドでインストールを実行し、アップデートをマージしてインストールします。後でさらにパッケージを追加すると、アップデートが再度実行され、必要なパッケージがすべてインストールされます。アップデートを個別に実行すると、キャッシュが更新され、パッケージのインストールが失敗する可能性があります。スクリプトによるインストールでは、フロントエンドを非対話型に設定し、インストールするには-yを渡す必要があります。インストールの最後にクリーニングとパージを行うと、レイヤーのサイズが最小限に抑えられます。
FROM debian
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
openssh-client \
sudo \
vim \
wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*