Dockerfile ARG
Dockerfileには、 ARG という定義命令があります。これは、dockerfile内で使用できる変数で、変数の値によって生成するイメージの中身を変えることができます。
環境変数であるENVとは異なり、Dockerfile 内でのみこの変数を使用することができます。
変数が使用できる定義命令は、ADD, COPY, WORKDIR, RUN, USER, ENV などで使えることが確認できました。
この変数は、シェルスクリプトの変数と同じように扱うことが出来ます。
基本的な使い方
FROM busybox
ARG hoge
RUN echo $hoge
docker build ./ --build-arg hoge=hello
出力結果に echo の出力として hello が表示されると思います。
デフォルト値
Dockerfile内でARGを使用する際に、デフォルト値を使用することができます。 --build-arg で変数が定義されていない場合は、デフォルト値が使用されます。
FROM busybox
ARG hoge="world"
RUN echo $hoge
また、デフォルト値は実際に変数を使用する場合にも指定可能です。
FROM busybox
ARG user
USER ${user:-some_user}
docker-compose v2 で args を使用する
docker-compose の v2 より、 args を使用できるようになりました。
--build-arg と同様に使用することが出来ます。実際の運用ではこちらを使うことが多いと思います。
version: '2'
services:
busybox:
build:
context: ./busybox/
args:
hoge: "hello world"
このように書くことも可能です。
version: '2'
services:
busybox:
build:
args:
- buildno=1
- user=someuser
出来ること
ARGによって生成されるイメージの中身を変えることができるため、ひとつの Dockerfile で出来ることが広がります。
entrypoint を切り替える
たとえば、master や slave によってentrypointの挙動を切り替える必要がある場合は、ファイル名のsuffixにARGを使用することで切り替えることができます。
ARG arg
COPY entrypoint_${arg} /entrypoint.sh
wget時のバージョン指定
バージョンアップ時などは、バージョンが冗長になってしまい、管理がし辛いですが、
ARGを使うととても綺麗にかけます。
ARG ver
RUN wget http://example.com/hoge-${ver}.tar.gz
RUN tar xzvf hoge-${ver}.tar.gz
WORKDIR hoge-${ver}
RUN ./configure
RUN make
RUN make install
sed
テンプレートエンジンのようなことをsedで実現
ARG arg="test"
COPY hoge.sh hoge.sh
RUN sed -i -e "s/{{arg}}/${arg}/g" hoge.sh
envsubst
envsubstを使って変数を展開することも可能です。
envsubst で 展開したい変数を指定するタイミングで展開されてしまうと困るので \$mode のようにすると良いです。
RUN apt-get install -y gettext
RUN cat /bin/entrypoint.sh | envsubst "\$mode" > /bin/entrypoint.tmp.sh
RUN mv /bin/entrypoint.tmp.sh /bin/entrypoint.sh
ENVとの使い分け
ENVでは、コンテナ内で環境変数として変数が定義されます。 ARG は、 Dockerfileのbuild時に一時的に変数が定義され、コマンドの実行時に展開されます。ENVを使用する場合は、CMDやENTRYPOINTによって実行されたコマンドに適しており、ARGは、変数を展開した状態でコンテナ内にファイルを配置したい場合に有効です。
ARGは変数を展開した状態でコンテナに状態を設定するという特性から、コンテナが管理するファイルには有効ですが、 VOLUMEによって管理されているディレクトリに配置されているファイルに対してはENVを使ったほうが便利な場面が多いです。