Dockerfile
ビルドプロセス時の removing itermediate container とか、Step とかってなんなんだ?
build context
build context とは、特定のPATHもしくはURLに存在するファイル群を指す
PATH であればローカルファイル。再帰的にサブディレクトリも含める
URL であれば Git リポジトリ。再帰的に Git submodule も含める
ビルド処理時に Docker deamon に送信される
イメージのファイルシステムから参照できるようになる
code:bash
# 下記のようにビルドした場合、/path/to/context 以下が context となる
cd /path/to/context
docker image build -t myimage:1.0 .
# 下記の場合、Git リポジトリが context となる
docker image build -t myimage:1.0 git@gitlab.com:tasuwo/my.git
基本的には、context にはアプリケーションの動作に必要なコードや成果物のみを含めるが、意図しないものを含んでしまう場合があるので注意が必要。
Git で .gitignore で管理対象のファイルを制御するように、Docker の場合は .dockerignore ファイルでコンテキストに含めるファイルを制御できる。
オプション
Dockerfile は context のルートに存在するのが慣例だが、-f フラグで別の場所にある Dockerfile を利用することもできる。
code:bash
docker build -f /path/to/a/Dockerfile .
-t フラグで、生成したイメージにタグ付けができる。
code:bash
docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
Docker daemon によるビルド
Docker daemon は、Dockerfile 内の指示を 1 つずつ実行する
各実行結果はイメージにコミットされる
実施後、送信された context は自動的に削除される
各指示は独立して実行されるので、例えば RUN cd /tmp のような何も影響を及ぼさない
可能であれば、Docker daemon は docker build の時間を短縮するために、中間イメージをキャッシュして使い回す
Docker save/export/load
save はイメージを保存する。イメージはレイヤ構造とそのメタ情報も含んでいる。一方で export で保存されるコンテナはファイルシステムだけが保存されるので、サイズ的には小さくなる。
docker save イメージを圧縮ファイルとして出力
docker export コンテナを圧縮ファイルとして出力
docker load コンテナ/イメージを取り込む
BuildKit
18.09 から、ビルドを実行するための新しいバックエンドとして BuildKit が利用できるようになった。 利用されていないビルドステージの検知のスキップ
独立したビルドステージの並列ビルド
ビルド中に、変更のあったcontextのファイルのみをインクリメンタルに送信する
ビルドコンテキスト内の利用していないファイルの検知とスキップ
外部の Dockerfile 実装の利用
などなど。DOCKER_BUILDKIT=1 オプションを利用すると良い。
フォーマット
INSTRUCTION が Dockerfile に対する指示。
code:Dockerfile
# Comment
INSTRUCTION arguments
Parser Directive
色々できるらしい
FROM
code:Dockerfile
# 必ず FROM から始めなければならない
FROM <ベースイメージ>
RUN
現在の image のトップのレイヤー上で任意のコマンドを実行し、その結果をコミットする
以下の2つの形式がある
RUN <command>
shell を利用する
シェルコマンドを実行する。デフォルトだと Linux では /bin/sh -c
Windows では cmd /S /C
デフォルトシェルは SHELL で変更可能
RUN ["executable", "param1", "param2"]
exec を利用する
渡す文字列を固定できる
実行可能な shell を含まないベースイメージでも利用できる
利用したいシェルがある場合は RUN ["/bin/bash", "-c", "echo hello"] のように直接指定できる
コマンドシェルを呼び出さない
通常のシェルプロセスが発生しない
RUN [ "echo", "$HOME" ] は $HOME を置換しない
シェルプロセスを発生させたければ、shell 形式を利用するか、RUN ["sh", "-c", "echo $HOME"] のように直接シェルを呼び出す
キャッシュについて
RUN apt-get dist-upgrade -y のような実行に対するキャッシュはデフォルトで有効
無効にしたければ ---no-cache
LABEL
イメージにメタデータを付与する
1つのイメージに複数のメタデータを付与できる
バージョンとか、description を追加するか
docker inspect で確認できる
MAINTAINER
deprecated
元々は Author を描くものだったが、LABEL が適している
EXPOSE
Docker に、コンテナが、実行時に特定のネットワークポートを listen することを教える
TCP あるいは UDP を指定可能 (デフォルトは TCP)
ポートの公開は実際には行わない。どのポートが公開されるか?を、イメージをビルドする、あるいはコンテナを実行する人に教える用途で利用する
ポートの公開は -p フラグを docker run に与えることで可能
-P で、EXPOSE したポートを公開することもできる
ENV
環境変数を設定する
設定した環境変数はビルドステージ内の全ての instructions 内で利用できる
設定した環境変数は、できたイメージからコンテナを実行した時に永続化されている
コンテナ内でも環境変数が持続してしまう
ビルド時にしか利用しない環境変数などは、ARG を利用するのが良い
docker inspect で確認が可能
docker run --env <key>=<value> で変更が可能
ADD
2つの形式がある
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
--chown は Windows では利用できない
<src> は context に対する相対パス、
ファイルやディレクトリをイメージのファイルシステムにコピーする
code:Dockerfile
ADD hom* /mydir/
ADD hom?.txt /mydir/
コピー先は、絶対パス もしくは WORKDIR からの相対パス
<src> は、context に対する 相対パス
context 内のファイルしか参照できない
ADD ../something /something のようなのは不可
ディレクトリだった場合、ディレクトリはコピーされず、その中身のみコピーされる
<dest> は、絶対パス、もしくは WORKDIR からの 相対パス
/ で終わっていない場合、そこ (<dest>) 自体にコピーされる
/ で終わっている場合、<dest>/<filename> に全てのコンテンツがコピーされる
<src> がワイルドカード等で複数指定されていたら、<dest> は / で終わるディレクトリである必要がある
<dest> が存在しない場合、パス内の存在しない全てのディレクトリは作成される
COPY
2つの形式がある
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
挙動はだいたい ADD と同じっぽい
USER
ユーザ名もしくはIDとグループを指定できる
RUN, CMD, ENTRYPOINT で利用される
特定のグループが指定されなかった場合、 root グループで実行される
WORKDIR
作業ディレクトリを設定する
設定以後の RUN, CMD, ENTRYPOINT, COPY, ADD で利用できる
指定先が存在しなかった場合作成される
複数回の利用が可能
ARG
ビルド時に docker build で --build-arg <varname>=<value> フラグを介して渡す値を定義できる
環境変数を設定する
デフォルト値も設定可能
docker history で見れてしまうので、秘匿情報は渡してはいけない
変数のスコープは、定義行以後のみ
ビルドステージが別になると引き継がれない
FROM が複数あると引き継がれない
ENV に上書きされる
引数から渡した値を ENV で利用して、image に永続化する、みたいなテクニックもある
code:dockerfile
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}
4 RUN echo $CONT_IMG_VER
Predefined なものもいくつかある
ビルドされた image には影響しないが、ビルドキャッシュには影響する
ONBUILD
STOPSIGNAL
HEALTHCHECK
SHELL
環境変数
限られた instruction でしか変数は展開されない。
ENTRYPOINT と CMD について