Use argument in Dockerfile

Dockerfile内で例えば

RUN wget https://releases.hashicorp.com/consul/0.7.2/consul_0.7.2_linux_amd64.zip

みたいなことをする場合、バージョンの部分を変数にできないか調べた(バージョン上げる度に複数ヶ所直すのが面倒)。

ARGインストラクションを使えばよさそう。

ARGインストラクションはdocker build時に使用可能な変数で、コンテナに環境変数を設定するENVインストラクションとは性質が異なる。

ARGは以下のようにして使える。

ARG version="0.7.2"
RUN wget https://releases.hashicorp.com/consul/${version}/consul_${version}_linux_amd64.zip

※ ARGインストラクションを使った変数名に-は使えないようなので注意。_は使える。

上の場合、ARG versionにデフォルト値0.7.2を設定していることになる。ビルド時にdocker build . --build-arg version="0.6.4"のように指定すれば、その値が使われる。

ENVとの違いをもう少し詳しく

docker inspectコマンドを使用して、ARGとENVで値をセットしてビルドした場合のそれぞれのイメージの差異を比較する。

ARGでセットした場合、ビルドしたイメージの環境変数はPATHのみ。

$ docker inspect -f "{{.Config.Env}}" baa5d63471ea
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin]

次に、以下のようにENVを使用するようにDockerfileを修正する。

- ARG version="0.7.2"
+ ENV version="0.7.2"
  RUN wget --no-check-certificate https://releases.hashicorp.com/consul/${version}/consul_${version}_linux_amd64.zip

再度ビルドした後にdocker inspectでイメージの情報を見てみると...。

$ docker inspect -f "{{.Config.Env}}" 1bf2817e38f2
[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin version=0.7.2]

環境変数にversionが追加された!

ENVとARGの使い分け

以下のように使い分ければ良さそう。

  • PATH環境変数など、「コンテナ内でも環境変数として利用したい」値はENVを使う
  • インストールするミドルウェアのバージョンなど、「ビルド時にのみに利用したい」値はARGを使う