speg03の雑記帳

主に未来の自分のために試したことなどを記録しています

HTTPプロキシ環境におけるdocker build

(追記 2016/06/25) Docker 1.9よりdocker build時に環境変数を渡せるようになっていました。 そのため、この記事に書いていたような面倒なことは必要なくなりました。

以下のようにHTTP_PROXY環境変数を渡しながらビルドすることができます。

$ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .

以下も参照してください。

(追記おわり)

概要

HTTPプロキシを経由しなければインターネットにアクセスできない環境において、インターネットアクセスが必要なdocker build(アプリケーションパッケージのインストールなど)を行うには環境変数の設定が必要になります。しかし、環境変数の情報をDockerfileに書いてしまうとプロキシ環境以外で使いにくくなってしまいます。

そこで、Dockerfileは環境によらず使えるように、プロキシ設定をDockerイメージに埋め込む方法について説明します。

例題

例として以下のようなDockerfileを作成するとします。fedora:21を使ってApacheをインストールしたDockerイメージを作成するものです。

FROM fedora:21
RUN yum update -y && yum install -y httpd && yum clean all

このままdocker buildしても、プロキシを越えられずyumコマンドの実行に失敗します。

$ docker build -t httpd .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM fedora:21
 ---> 834629358fe2
Step 1 : RUN yum update -y && yum install -y httpd && yum clean all
 ---> Running in ad13de39b3ac

(中略)

Cannot retrieve metalink for repository: fedora/21/x86_64. Please verify its pat
h and try again
INFO[0005] The command [/bin/sh -c yum update -y && yum install -y httpd && yum
clean all] returned a non-zero code: 1

このDockerfile自体にENV http_proxy http://proxy.example.com:8080とプロキシ設定を追記しても構いませんが、プロキシ環境に依存したDockerfileとなってしまいます。Dockerfileには変更を加えず、特定の環境に依存しないようにします。

ONBUILDによるプロキシ設定の埋め込み

ベースとなるDockerイメージにONBUILDでプロキシ設定を埋め込むようなスクリプトを作成します。スクリプトの名前は何でもよいですが、ここではdocker-http-proxyとします。

ベースとなるDockerイメージ(FROMで指定)と作成するDockerイメージ(docker build -tで指定)の両方に同じ名前を指定しています。

#!/bin/sh

if [ $# != 1 ]; then
   echo "Usage: $0 DOCKER_IMAGE"
   exit 1
fi

cat <<EOF | docker build -t $1 -
FROM $1
ONBUILD ENV http_proxy $http_proxy
ONBUILD ENV https_proxy $https_proxy
ONBUILD ENV no_proxy $no_proxy
EOF

プロキシ設定に関する環境変数は実行中のシェルですでに設定されているものとします。設定する値は適宜読み替えてください。

export http_proxy=http://proxy.example.com:8080
export https_proxy=http://proxy.example.com:8080
export no_proxy=127.0.0.1,localhost

例として、fedora:21イメージにプロキシ設定を埋め込む場合は以下のように実行します。

$ docker-http-proxy fedora:21
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM fedora:21
 ---> 834629358fe2
Step 1 : ONBUILD env http_proxy http://proxy.example.com:8080
 ---> Running in 7293472d9793
 ---> 35244c2f0c76
Removing intermediate container 7293472d9793
Step 2 : ONBUILD env https_proxy http://proxy.example.com:8080
 ---> Running in 4a52cac11df4
 ---> 5190135a8d40
Removing intermediate container 4a52cac11df4
Step 3 : ONBUILD env no_proxy 127.0.0.1,localhost
 ---> Running in fedf6baa373a
 ---> eda7740be6ee
Removing intermediate container fedf6baa373a
Successfully built eda7740be6ee

これでプロキシ設定済みのfedora:21イメージが完成しました。

最初の例に挙げたDockerfileを再びビルドしてみます。

$ docker build -t httpd .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM fedora:21
# Executing 3 build triggers
Trigger 0, ENV http_proxy http://proxy.example.com:8080
Step 0 : ENV http_proxy http://proxy.example.com:8080
 ---> Running in 1d862437b875
Trigger 1, ENV https_proxy http://proxy.example.com:8080
Step 0 : ENV https_proxy http://proxy.example.com:8080
 ---> Running in 2483039ae324
Trigger 2, ENV no_proxy 127.0.0.1,localhost
Step 0 : ENV no_proxy 127.0.0.1,localhost
 ---> Running in 6cf89a748f98
 ---> c00437a577bd
Removing intermediate container 1d862437b875
Removing intermediate container 2483039ae324
Removing intermediate container 6cf89a748f98
Step 1 : RUN yum update -y && yum install -y httpd && yum clean all
 ---> Running in 3b5ba7989288

(中略)

Complete!
Cleaning repos: fedora updates
Cleaning up everything
 ---> 2c8f2b5806be
Removing intermediate container 3b5ba7989288
Successfully built 2c8f2b5806be

今度はONBUILDで埋め込んでおいたプロキシ設定が読み込まれ、正常にビルドが終了しました。

すでにONBUILDが含まれているイメージの場合

今回は、ONBUILDを利用してプロキシ設定を行いました。この方法では、すでにONBUILDによる処理が設定されていた場合に共存することができません。ONBUILDは次に行うdocker buildでしか効果を持ちません。このような場合には、さらに元のベースイメージに対してプロキシ設定を行うことになります。

例えば、すでにONBUILD処理が記述されたrails:onbuildイメージを考えてみます。rails:onbuildイメージはruby:2.2.0イメージをベースとしています(執筆時点)。

ruby:2.2.0イメージにプロキシ設定を追加します。

$ docker-http-proxy ruby:2.2.0

次にrails:onbuildイメージを手元で作成します。

$ git clone https://github.com/docker-library/rails.git
$ cd rails/onbuild
$ git checkout 3c87a6cf32d01204b95ba12a266d13c8c32e5358
$ docker build -t rails:onbuild .

これでプロキシ設定が追加されたrails:onbuildイメージが完成します。