kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Dockerfile の ARG を使って FROM を変数化する

コンテナイメージを作るときに Dockerfile の FROM に指定する「イメージ名」「タグ名」をビルドごとに変えて設定したく,Dockerfile の ARG を使って実現できた.試しながら学んだポイントをまとめる❗️

Dockerfile 例

例えば,以下の Dockerfile では ARG を使って VERSION を変数化していて,docker build コマンドを実行するときに --build-arg オプションを使うと変数に値を挿入できる.もし --build-arg オプションを使わなかった場合はデフォルト値(今回の例だと latest)のままになる.

ARG VERSION=latest
FROM nginx:${VERSION}

ARG の仕様や注意点などはドキュメントに詳しく載っている.

docs.docker.com

実際に docker build --build-arg コマンドを実行して,NGINX 1.22NGINX 1.23 のコンテナイメージを作ったところ,期待通りに起動できた.よって,Dockerfile の ARG を使うことで「Dockerfile」を共通化できるようになった❗️

NGINX 1.22

$ docker build . --tag my-nginx:1.22 --build-arg VERSION=1.22
$ docker run -p 8080:80 my-nginx:1.22
(中略)
2023/03/07 00:00:00 [notice] 1#1: nginx/1.22.1
(中略)

NGINX 1.23

$ docker build . --tag my-nginx:1.23 --build-arg VERSION=1.23
$ docker run -p 8080:80 my-nginx:1.23
(中略)
2023/03/07 00:00:00 [notice] 1#1: nginx/1.23.3
(中略)

ARG のスコープに気を付ける

ドキュメントに載っている通り,FROM より前に設定した ARG はビルドとは異なるスコープ(ビルドステージの外側)になる点は理解しておく必要がありそう.

An ARG declared before a FROM is outside of a build stage, so it can’t be used in any instruction after a FROM. To use the default value of an ARG declared before the first FROM use an ARG instruction without a value inside of a build stage:

実際に確認するため,以下のように Dockerfile に VERSIONversion.txt に書き出す1行を追加した.コンテナを起動して version.txt を確認すると,スコープが異なるためファイルの中身は「ブランク」だった.

ARG VERSION=latest
FROM nginx:${VERSION}
RUN echo ${VERSION} > version.txt

正しくは FROM の後にもう一度,デフォルト値は指定せずに VERSION を追加する必要がある.

ARG VERSION=latest
FROM nginx:${VERSION}
ARG VERSION
RUN echo ${VERSION} > version.txt

すると,期待通りに version.txtVERSION を書き出せた❗️

# cat version.txt
1.23

# cat version.txt
1.23

# cat version.txt
latest