DockerHub公式の言語Stack
DockerHub Official Repos: Announcing Language Stacks | Docker Blog
DockerHubには公式のレポジトリがある.そこにはUbuntuやCentos,MySQLやPostgres,MongoといったDockerイメージがコミュニティーベースで,つまりより汎用的に使える形で開発され集められており,ベースイメージとして簡単に使えるようになっている.
今までは,OSのディストリビューションや,Webサーバ,DBなどがメインだったが,公式として各種プログラミング言語のベースイメージも公開された.現状(2014年9月時点)では,c/c++(gcc),clojure,golang,hylang,java,node,perl,PHP,python,rails,rubyがある.
特徴
この公式の言語stackには以下の3つの特徴がある.
- buildpack-depsイメージをベースにしている
- 各Versionをサポートしている
- ONBUILDをイメージもサポートしている
これらを簡単に説明する.
Buildpack-deps
buildpack-depsイメージというのは,HerokuのStackのようなイメージで,各言語を動かすために必要な基本的な依存関係等がインストールされている.
Dockerfileは以下.
FROM debian:wheezy
RUN apt-get update && apt-get install -y \
autoconf \
build-essential \
imagemagick \
libbz2-dev \
libcurl4-openssl-dev \
libevent-dev \
libffi-dev \
libglib2.0-dev \
libjpeg-dev \
libmagickcore-dev \
libmagickwand-dev \
libmysqlclient-dev \
libncurses-dev \
libpq-dev \
libpq-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
libxslt-dev \
libyaml-dev \
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion \
&& rm -rf /var/lib/apt/lists/*
よく言語をインストールする際に依存で入れるべきものが揃っている.これを元に各言語スタックは作成されるので,これらの依存のインストールし忘れなどを防ぐことができる.
Version
各言語スタックは適切にバージョンがタグとして付加されているため,使いたいバージョンを選んで使うことができる.例えば,rubyのv2.1.3を使いたければruby:2.1.3イメージを,pythonの3.4.1を使いたければpython:3.4.1イメージを選択できる.
ONBUILD
言語スタックでは,普通のイメージに加えて,ONBUILD
イメージもサポートされている.
ONBUILD
はDockerfileのコマンドで,これに続いて別のDockerfileコマンドを記述する.そして,そのDockerfileを元にビルドされたイメージをFROMとしてDockerfileを新たに作成し,ビルドを実行すると,上でONBUILD
と共に記述したコマンドが実行される.つまり,Dockerfileに親子関係を持たせることができる(詳しくは,“DockerfileのONBUILD”に書いた).
これは結構良くて,言語スタックでは,依存関係ファイルのADD
とインストールの実行,アプリのADD
に使われている.例えば,RailsのONBUILDイメージの場合は,GemfileとGemfile.lockのADD
,RailsアプリのADD
が記述されている.つまり,RailsのONBUILDイメージを使えば,特殊なことをしていない限りDockerfileにほとんど何も書かなくて良い.
また,ここにはコミュニティ開発の良さも含まれていて,例えば,“RailsアプリをDockerにデプロイするときにGemfileを変更してなければBundle Installをスキップする方法”といった,Dockerfileのベストプラクティスがちゃんと含まれている.
使ってみる
とりあえず,いくつか軽く使ってみる.
rails
まず,railsイメージ.ruby:2.1.2イメージを元に作られたonbuildイメージを使う.このイメージは以下のDockerfileで作成されている.いくつかのONBUILD
と,Railsを動かすのに必要なnodeのインストールなどが記述されている.
FROM ruby:2.1.2
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ONBUILD ADD Gemfile /usr/src/app/
ONBUILD ADD Gemfile.lock /usr/src/app/
ONBUILD RUN bundle install --system
ONBUILD ADD . /usr/src/app
RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
EXPOSE 3000
CMD ["rails", "server"]
これを使うのは簡単.実際にサンプルアプリを作って動かしてみる.まず,以下でDockerイメージをbuildする.
$ rails new sample-app
$ cd sample-app
$ echo 'FROM rails:onbuild' > Dockerfile
$ docker build -t tcnksm/sample-rails .
1行のDockerfileを作るだけで良い.それをbuildするとONBUILD
により,Gemfile
とGemfile.lock
のADD
とbundle install
が実行される.そして,カレントディレクトリのアプリケーションがADD
される.
後は以下を実行すれば,親DockerfileのCMD
に記述されたrails server
で,コンテナが起動する.
$ docker run -d -p 3000:3000 tcnksm/sample-app
$ curl http://<container-ip>:3000
golang
golangだとアプリケーションを動かすより,コンテナによるクリーンな環境でのコンパイルに使うのが良さそう.それも簡単にできる.
例えば,tcnksm/ghrをgo-1.3.1イメージでコンパイルする.
$ git clone https://github.com/tcnksm/ghr
$ cd ghr
$ docker run --rm -v "$(pwd)":/usr/src/ghr -w /usr/src/ghr golang:1.3.1 bash -c 'go get -d ./... && go build -v'
go-1.2イメージでコンパイルする.
$ docker run --rm -v "$(pwd)":/usr/src/ghr -w /usr/src/ghr golang:1.2 go build -v
go-1.3.1のクロスコンパイル用イメージでwindows/386
にクロスコンパイルする.
$ docker run --rm -v "$(pwd)":/usr/src/ghr -w /usr/src/ghr -e GOOS=windows -e GOARCH=386 golang:1.3.1-cross go build -v
コントリビュートしたい
プロジェクトを作って[email protected]にメールすれば,公式のDockerHubレポジトリとして取り込んでもらえる可能性もある.
以下のガイドラインに従う.
まとめ
Dockerが出たときって,Dockerfileを書くのは時代に逆行しているから自動生成しようといった意見やツールを見た.実際,自分でも“rbdockというRuby/Rails/Sinatra用のDockerfileを生成するgem”をつくったりした.でも,DockerHubのおかげで良いDockerfileをみんなで作って,そのイメージを使えるだけにしようという流れになっている.どんどん簡単になっていく.
ただ,いきなり使うのは危険で,例えばONBUILDとか何が仕込まれてるかbuildしないとわからい.ので,使う前にちゃんとDockerfileに一度目を通すのが大事かなと.その辺はOSSのツールを使うときと同じ.