docker-composeを使うと複数コンテナの管理が便利に

docker-composeを使うと、複数のコンテナから構成されるサービスを従来よりも簡単に管理できるようになる。

# dockerだけで管理する場合の不便さ

たとえば dockerだけでmysqlとgitbucket・redmine・リバースプロキシ(nginx)を立ち上げる場合には、次のようなコマンドをシェルスクリプト化しておく必要があった。linkオプションがあるので、コンテナの立ち上げ順序も気にしなればいけない。

![構成図](https://qiita-image-store.s3.amazonaws.com/0/48238/db5f7204-ad83-17b6-4009-61e5180bc760.png)

``` sh:run.sh
# mysql
docker run --name mysql \
  -d \
  -p 3306:3306 \
  --volumes-from data-mysql \
  -e 'MYSQL_ROOT_PASSWORD=password' \
  mysql
# redmine
docker run --name redmine \
  -d \
  --link mysql:mysql \
  --volumes-from data-redmine \
  --volumes-from data-gitbucket  \
  -e 'REDMINE_RELATIVE_URL_ROOT=/redmine' \
  -e 'DB_USER=redmine' \
  -e 'DB_NAME=redmine' \
  -e 'DB_PASS=password' \
  -e 'SMTP_USER=address@hoge.com' \
  -e 'SMTP_PASS=password' \
  sameersbn/redmine:2.6.3
# gitbucket
docker run --name gitbucket \
  -d \
  -p 29418:29418 \
  --volumes-from data-gitbucket \
  f99aq8ove/gitbucket \
  java -jar /opt/gitbucket.war --prefix=/gitbucket
# reverse-proxy
# あらかじめ myname/proxy でイメージをビルドしておく
docker run --name proxy
  -d \
  --link redmine:redmine
  --link gitbucket:gitbucket
  -p 80:80 \
  myname/proxy
```
終了や再起動も1つ1つコンテナの名前を指定して行うので、コンテナが増えてくると管理が面倒になってくる。

```
# まとめて終了
docker stop gitbucket
docker stop redmine
docker stop mysql
docker stop proxy
# まとめて削除
docker rm gitbucket
docker rm redmine
docker rm mysql
docker rm proxy
```

# docker-composeを使用した場合の便利さ

docker-composeを導入すると、先程の構成を次のようなYAMLファイルで管理できる。YAMLファイルの書式はほぼdocker runのオプションと対応しているので、特に難しいところはない。

```yaml:docker-compose.yml
# mysql
mysql:
  image: mysql
  volumes_from:
    - data-mysql
  ports:
    - "3306:3306"
  environment:
    MYSQL_ROOT_PASSWORD: password
# redmine
redmine:
  image: sameersbn/redmine:2.6.3
  volumes_from:
    - data-gitbucket
    - data-redmine
  links:
    - mysql:mysql
  environment:
    REDMINE_RELATIVE_URL_ROOT: /redmine
    DB_USER: redmine
    DB_PASS: password
    SMTP_USER: address@hoge.com
    SMTP_PASS: password
# gitbucket
gitbucket:
  image: f99aq8ove/gitbucket
  volumes_from:
    - data-gitbucket
  ports:
    - "29418:29418"
  command: java -jar /opt/gitbucket.war --prefix=/gitbucket
# reverse-proxy
proxy:
  build: myproxy
  links:
    - gitbucket:gitbucket
    - redmine:redmine
  ports:
    - "80:80"
```
ディレクトリ構成は次のようにする。
<pre>
myservices
├─ docker-compose.yml
└─ myproxy
   └─ Dockerfile
</pre>
`docker-compose.yml`と同じ階層に移動して`docker-compose up -d`をすると、ビルド・プルを自動で行ってから、linksの依存関係に沿った順番でコンテナを起動してくれる。

```sh
# YAMLに「build:」があれば、そのイメージをまとめてビルド
docker-compose build
# YAMLに「image:」があれば、そのイメージをまとめてプル
docker-compose pull
# docker-compose build, docker-compose pullをした後にdocker run
docker-compose up -d
# 個別のサービスを指定することもできる。依存関係がある場合は関係するコンテナすべてが起動するので、この場合は redmine と mysql が両方起動する
docker-compose up -d redmine
# 関係するコンテナすべての出力を表示
docker-compose logs
# 関係するコンテナをまとめて終了
docker-compose stop
# 関係するコンテナをまとめて削除
docker-compose rm
```

筆者はこれまでdocker stopやdocker rmコマンドをまとめたシェルスクリプトを使用してサービスの管理を行っていたが、docker-composeでそのあたりの管理が明らかに楽になったと感じた。既にdockerを使っている人にとっては新たな知識もほとんど必要なく、docker-composeはdockerを使っていく上で必須のツールになっていくのではないかと思う。

# OSXでCERTIFICATE_VERIFY_FAILEDと表示されてしまう場合

__以下はDockerToolbox登場以前の情報です。最新のOSXと[Docker Toolbox](https://www.docker.com/toolbox)の構成であれば、特に問題なくdocker-composeが使用できました。__

このチケットでの議論が参考になった。
https://github.com/docker/compose/issues/890

* opensslを適合するバージョンにする
* pythonのバージョンを適合するものにする
* docker-composeはpipからインストール

docker公式のシェルスクリプトを使うと、docker-composeが動作する環境にお膳立てしてくれる
https://github.com/docker/compose/blob/master/script/prepare-osx

# docker-compose公式ドキュメント
* [ユーザーガイド](https://docs.docker.com/compose/)
* [インストール方法](https://docs.docker.com/compose/install/)
* [コマンドリファレンス](https://docs.docker.com/compose/cli/)
* [YAMLリファレンス](https://docs.docker.com/compose/yml/)

# こちらもどうぞ!

* [Dockerで即実行できる、社内・自宅向けオープンソースWebアプリ - Qiita](http://qiita.com/y_hokkey/items/406b5a8c4bc15354d069)
* [Vagrant+CoreOSでdocker-composeをプロビジョニングする - Qiita](
http://qiita.com/y_hokkey/items/c9a740b3f3d800abdb67)