DockerfileのARGはビルドキャッシュにどう影響するのか、どこに書くべきなのか

スポンサーリンク

Dockerビルド時にパラメータを与えたいときにDockerfileで定義し、–build-argオプションと合わせて使うARG。

それをどこに書くか考えたときに

  • 最初に宣言されていたほうが読みやすい気もする
  • それで不要なキャッシュミスが起こるとしたら嫌

と悩んだのでどういう仕様でどうすべきなのか調べてみました。

そもそも基本

ARGは書いた行以降で有効になります

↓なのでこういうのはエラーになります。

FROM alpine
RUN touch $foo
ARG foo

ARGとキャッシュ

公式ドキュメントには、
ARGが変わった場合、(定義ではなく)最初の使用の時にキャッシュミスが起こる。ただし全てのRUNはARGの値を環境変数として暗黙的に使っているのでキャッシュミスを起こす。
というようなことが書かれています。

実験

ARGを最初に宣言

まずARGを上のほうで定義して、–build-argを変更するとどうなるか見てみます。

Dockerfile

FROM alpine

ARG foo

# ARGを使用しないしRUNでもない
COPY hoge.txt hoge.txt
# ARGを使用しないRUN
RUN touch a.txt
## ARGを使用するRUN
RUN touch ${foo}.txt

これを–build-argを変えて2度ビルドしてみます。

# 1回目
$ docker build -t argtest --build-arg foo=foo .
(ただの新規ビルドなので省略...)

# 2回目
$ docker build -t argtest --build-arg foo=bar .
Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM alpine
 ---> f70734b6a266
Step 2/5 : ARG foo
 ---> Using cache
 ---> 3745b7b0341c
Step 3/5 : COPY hoge.txt hoge.txt  # キャッシュ使用
 ---> Using cache
 ---> 2d217e6c362f
Step 4/5 : RUN touch a.txt  # キャッシュミス
 ---> Running in 60bbfe069aed
Removing intermediate container 60bbfe069aed
 ---> 37d7272ba87a
Step 5/5 : RUN touch ${foo}.txt
 ---> Running in e5e45a313f73
Removing intermediate container e5e45a313f73
 ---> 96c05a7eef27
Successfully built 96c05a7eef27
Successfully tagged argtest:latest

ドキュメント通り、ARGを使っていないRUNでもキャッシュが使われていませんね。

ARGを使用する直前で宣言

ARGをそれを使用するRUNの直前に変えてみます。

Dockerfile

FROM alpine

# ARGを使用しないしRUNでもない
COPY hoge.txt hoge.txt
# ARGを使用しないRUN
RUN touch a.txt
# 使用する直前で定義
ARG foo
## ARGを使用するRUN
RUN touch ${foo}.txt

ビルド

# 1回目
$ docker build -t argtest --build-arg foo=foo .
(省略...)

# 2回目
$ docker build -t argtest --build-arg foo=bar .
Sending build context to Docker daemon  3.072kB
Step 1/5 : FROM alpine
 ---> f70734b6a266
Step 2/5 : COPY hoge.txt hoge.txt
 ---> Using cache
 ---> 22abac6ef40c
Step 3/5 : RUN touch a.txt  ## キャッシュ使用
 ---> Using cache
 ---> 76402ca8ed9a
Step 4/5 : ARG foo
 ---> Using cache
 ---> 723ae15aa137
Step 5/5 : RUN touch ${foo}.txt  # ここでキャッシュミス
 ---> Running in 46f333bda19d
Removing intermediate container 46f333bda19d
 ---> f0f795e9e70e
Successfully built f0f795e9e70e
Successfully tagged argtest:latest

最初の例ではキャッシュミスになっていたRUN touch a.txtがUsing cacheになっています。

結論

ARGを直接使わないRUNにもキャッシュミスを起こすので、ARGは使用するRUNの直前で書いたほうが良い。

コメント

タイトルとURLをコピーしました