DockerfileのONBUILD
Docker 0.8においてONBUILD
というDockerfile用のコマンドが導入された.0.8ではOSXのdocker clientが脚光を浴びたが,このONBUILD
はかなり強力な機能.リリースノートはこちら.ONBUILD
の公式ドキュメントはこちら.
ONBUILD
を使うと,次のビルドで実行するコマンドをイメージに仕込むことができるようになる.つまり,ベースイメージにONBUILD
によるコマンドを仕込み,別のDockerfileでそのベースイメージを読み込みビルドした際に,そのコマンドを実行させるということが可能になる.要するに,親Dockerfile
のDockerfileコマンドを子Dockerfile
のビルド時に実行させることができる機能.
これは,アプリケーション用のイメージを作るときや,ユーザ特有の設定を組み込んだデーモン用のイメージを作るときなどに有用になる.また,オリジナルのHerokuのBuildpack的なものを作ることもできる.
言葉では伝えられないので簡単に動作例を示す.例えば,以下のようなDockerfile.base
を準備する.
# Docekerfile.base
FROM ubuntu
ONBUILD RUN echo "See you later"
これをtcnksm/echo_base
という名前でビルドする.
$ docker build -t tcnksm/echo_base - < Dockerfile.base
Step 0 : FROM ubuntu
Pulling repository ubuntu
...
f323cf34fd77: Download complete
---> 9cd978db300e
Step 1 : ONBUILD RUN echo "See you later"
---> Running in 9e42ede94d60
---> e18fdd8d9fa8
RUN echo
は実行されていない.
次に,このtcnksm/echo_base
を基にした別のイメージを作成するDockerfile
を準備する.
FROM tcnksm/echo_base
tcnksm/echo
という名前でビルドする.
$ docker build -t tcnksm/echo .
Uploading context 3.584 kB
Uploading context
Step 0 : FROM tcnksm/base
# Executing 1 build triggers
Step onbuild-0 : RUN echo "See you later"
---> Running in cddf3cf85ff8
See you later
---> 9f0189c1e902
---> 9f0189c1e902
Successfully built 9f0189c1e902
ベースイメージtcnksm/echo_base
で仕込んだRUN echo ..
が実行された.これがONBUILD
の機能.
では,実際の開発プロセスにおいてどのように使えるか.
Apache base image
/var/www以下のhtdocsを表示する単純なDockerアプリーションを作るとする.この場合Dockerfile
には,apacheのインストール,Apacheの起動コマンドの登録,/var/www/以下へのhtdocsの追加などを書くことになる.あとはこのDockerfile
をコピーしてビルドすれば,どこでもこのアプリケーションを動作させることができる.
新しくhtdocsを更新したい場合は,ビルドし直す,scp
できるようにしてファイルをコンテナ内にぶっ込む,volume
機能を使ってファイルをマウントする,などが考えられる.
ONBUILD
を使えば,ファイルの更新を考慮したイメージを作成することができる.つまり,親Dockerfile
でApacheのインストールなどの基本的なConfigurationを行う一方で,更新がかかるhtdocsの/var/www/への追加は子Dockerfile
のビルド時に実行させることが可能になる.これを実現する親Dockerfile
は以下のようになる.
# Dockerfile.base
FROM ubuntu:12.04
RUN apt-get update
RUN apt-get install -y apache2
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ONBUILD ADD . /var/www/
EXPOSE 80
ENTRYPOINT ["/usr/sbin/apache2"]
CMD ["-D", "FOREGROUND"]
カレントディレクトリを/var/www
に追加する部分をONBUILD
で記述する.あとは,ベースイメージをビルドし,レジストリにpush
しておく
$ docker build -t tcnksm/apache_base - < Dockerfile.base
$ docker push
Apache application image
htdocsを開発する.
$ echo "<h1>Hello, docker</h1>" > index.html
開発が終了したら,以下のようなDockerfile
を準備しビルドする.
FROM tcnksm/apache_base
$ docker build -t tcnksm/apache .
ビルドすると,親Dockerfile
で記述したONBUILD
が実行され,カレントディレクトリのhtdocsがイメージの/var/www/以下に追加される.あとは,このイメージを好きなところにデプロイして起動するだけ.
$ docker run -p 80:80 tcnksm/apache
開発方法
htdocsの開発中に実際にapacheを起動して,ブラウザで動作確認などができるとよい.以下のようにvolume
でカレントディレクトリをベースイメージの/var/wwwにマウントして起動すれば,リアルタイムで更新を確認しつつ開発を進めることができる.
$ docker run -p 80:80 -v $(pwd):/var/www -t tcnksm/apache_base
vagrant share
のように外部の開発者とやり取りしつつ開発したいなら,ngrokを使ってDocker share的なこともできる.
開発が終了したら,上のDockerfileを使って最終イメージをビルドし,イメージをデプロイする.例えば,Orchardにデプロイするには以下のようにする(Orchardの使い方は,“OrchardにDockerアプリケーションをデプロイ”に書いた).
$ orchard docker build -t tcnksm/apache .
$ orchard docker run -d -p 80:80 tcnksm/apache