octopus_blocks_die

DockerfileでDockerイメージの作成を自動化するでは、Dockerfileを使ってコンテナイメージを自動生成した。しかし、複数コンテナを操作する時は手動ないしはシェルスクリプト経由で依存関係を考慮してdokcerコマンドを実行する必要があった。今回はDocker Composeを利用して複数のコンテナの依存関係加味した一括操作を実現する。

システム構成

以下のようなシステムをコンテナを組み合わせて実現する。

system_architecture

検証環境

➤  docker version
Client:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.3
 Git commit:   a34a1d5
 Built:        Fri Nov 20 17:56:04 UTC 2015
 OS/Arch:      darwin/amd64

Server:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.2
 Git commit:   a34a1d5
 Built:        Fri Nov 20 13:12:04 UTC 2015
 OS/Arch:      linux/amd64

コンテナイメージを組み合わせて1つのシステムを構築する

リバースプロキシ、Redmine、DB(PostGreSQL)のコンテナをdocker runで順番に起動してシステムを完成させる。

まずはリバースプロキシコンテナを起動する。このときリバースプロキシとなるNginxとredmineを--link redmine:redmineオプションをつける必要はない。代わりにRedmineコンテナ起動時にVIRTUAL_HOSTの設定をする。

docker run --name rproxy -d \
  --publish 80:80 \
  --volume /var/run/docker.sock:/tmp/docker.sock:ro \
  jwilder/nginx-proxy:latest

続いて、DBコンテナを起動する。

docker run  --name db -d \
  --env POSTGRES_PASSWORD=secret \
  --env POSTGRES_USER=redmine \
  postgres:9.5

最後にRedmineコンテナを起動する。

docker run  --name redmine -d \
  --link db:postgres \
  --env VIRTUAL_HOST=redmine.example.com \
  redmine:2.6.8

redmine.example.comでDockerホストのipを名前解決出来るように/etc/hostsを書き変えた後、ブラウザでhttp://redmine.example.comにアクセスする[1]とRedmineのトップ画面が表示される。

このシステムを止めるときは以下の順でコマンドを実行する。

➤  docker stop redmine
➤  docker stop db
➤  docker stop rproxy

システムを起動するときはその逆だ。

➤  docker start proxy
➤  docker start db
➤  docker start redline

以上から分かる通り、3つのコンテナから構成される簡単なシステムなのでまだ手作業で実行順序を容易に決定できる。一方で、数十、数百のコンテナからなるシステムとなると依存環境を考慮したコマンド実行は難易度が飛躍的に上がる。

Docker Composeとは

いよいよこの記事の本編に入る。コンテナを組み合わせてシステムを作る時コンテナの依存関係が重要になってくる。先ほどの例だと、リバースプロキシ、DB、Redmineのコンテナの順にdocker runを実行する。コンテナを終了するときはその逆順にdocker stopだ。システムが大きくなってくるとこれを手作業やスクリプトでやるのはしんどい。そこでDocker Composeを使う。

Docker Composeの役割は複数のコンテナを管理することであり、コンテナ間の依存関係をdocker-compose.ymlに記述する。これを利用することで先ほど手作業で行っていた起動、終了をdocker-compose updocker-compose stopで一括で操作可能になる。

Docker ComposeでRedmineの構築をする

Redmineを構築するためのdocker-compose.ymlを以下の内容で作成する。これは先程手作業で実施した内容と同じである。

rproxy:
  image: jwilder/nginx-proxy:latest
  ports:
    - "80:80"
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock:ro
db:
  image: postgres:9.5
  environment:
    - POSTGRES_PASSWORD=secret
    - POSTGRES_USER=redmine
redmine:
  image: redmine:2.6.8
  links:
    - db
  environment:
    - VIRTUAL_HOST=redmine.example.com
  volumes:
    - /srv/docker/redmine/redmine:/home/redmine/data

ファイルが作成されたらdocker composeのコマンドを実行してしばらく待つ。

docker-compose up

これだけで、DB、Redmineの順にコンテナを起動してくれる。ブラウザを起動してredmine.example.comにアクセスすればRedmineのトップページが表示されるはずだ。 起動したシステムを停止する時も依存関係を考慮して停止できる。

docker-compose stop

システムを破棄するときも一括で操作できる。

docker-compose rm

非常に簡単だ。

Docker Composeの使い方

Docker Composeは公式ドキュメントが良くまとまっている。

また、事例から学びたいときは公式がWordpressやRailsを構築するためのdocker-compose.ymlを用意してくれているのでそちらを参照すること。

余談

Docker HubにあがってるRedmine Officialのレポジトリはドキュメントが全然整備されてないから使い方が良くわからない。ちゃんと使うなら、自分でdocker-library/redmine · GitHubを読んだほうが良いと思う。

参考

Docker Compose

Docker Volumeについて

DockerによるRedmineの構築

Nginx

[1] キャッシュが残っていると上手く表示されない場合があるので、ChromeならばCmd + Shift + Nで新規セッションを張るか、Cmd + Shift + Deleteでキャッシュを削除することをおすすめする。