Docker imageを作る時、ほぼほぼ中身が一緒だけとversionだけ違くてversionごとにDockerfileを作っていました。。。
何か修正したいときに2ファイルをダブルメンテするのが大変だったのでDockerfileに変数を渡して動きを変えられないか調べてみました。
結論
ARG
という定義を使えば良いです!
基本的な使い方
ポイント
・Dockerfileでは「ARG」で変数を定義する・変数の展開は「${変数名}」
・変数はdocker build時に「–build-arg」で指定する
ARG JAVA_VERSION
FROM openjdk:${JAVA_VERSION}
$ docker build --build-arg JAVA_VERSION=11 .
逆引き解説
ここからはARG
の使い方について逆引きでまとめます。
デフォルト値の設定
変数名=デフォルト値
で記述すればOK!
ARG JAVA_VERSION=11
FROM openjdk:${JAVA_VERSION}
複数のARGを扱う
--build-arg
を複数指定すればOK!
ARG JAVA_VERSION
ARG IMAGE_NAME
FROM ${IMAGE_NAME}:${JAVA_VERSION}
$ docker build --build-arg IMAGE_NAME=openjdk --build-arg JAVA_VERSION=11 .
1つのDockerfileで複数のイメージを作成
例えば以下のようなDockerfileがあるとします
FROM openjdk:17
# COPY, RUNなど
ENTRYPOINT [ "/entrypoint.sh" ]
FROM openjdk:11
# COPY, RUNなど
ENTRYPOINT [ "/entrypoint.sh" ]
サンプルなので記述量が少ないですが、実務で使っているともっと複雑な定義になりがちで、何か変更が必要になるとダブルメンテが必要になるので面倒です。
ARG
を使うと以下のように一つのファイルで複数のイメージに対応することができます。
ARG JAVA_VERSION=11
FROM openjdk:${JAVA_VERSION}
# COPY, RUNなど
ENTRYPOINT [ "/entrypoint.sh" ]
# java11のイメージを作成したい時(デフォルト値)
$ docker build .
# java17のイメージを作成したい時
$ docker build --build-arg JAVA_VERSION=17 .