Docker Compose で複数のコンテナを管理する

# 複数のコンテナを管理する
[家庭内サーバ](http://qiita.com/flny/items/0a838878473f321c4db1)を構成するにあたり いくつかのサービスをdockerコンテナに押し込めて来ました。
[samba](http://qiita.com/flny/items/ee3d443f84128b0202a7)
[unbound](http://qiita.com/flny/items/c0fd01db5fb3de6f8098)
[ffmpeg](http://qiita.com/flny/items/798547356dcc47239702) (サービスじゃないけど)
[MiniDLNA](http://qiita.com/flny/items/63976669a6f58976fa93)
今のところ各コンテナ間に依存関係はないものの、コンテナ作成時のパラメータ(docker run に与えるパラメータ)を気にするのが若干面倒になってきたため Docker Composeを使ってコンテナを管理してみます。

# Docker Composeをインストールする
[公式ドキュメント](https://docs.docker.com/compose/install/)に従い、curl でバイナリをダウンロードして /usr/local/bin/ にコピーします。

```
$ sudo -i sh -c "curl -L https://github.com/docker/compose/releases/download/1.5.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   600    0   600    0     0    810      0 --:--:-- --:--:-- --:--:--   810
100 7739k  100 7739k    0     0   564k      0  0:00:13  0:00:13 --:--:--  537k

$ sudo -i chmod +x /usr/local/bin/docker-compose
$ sudo -i sh -c "curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose --version | awk 'NR==1{print $NF}')/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  8571  100  8571    0     0  33739      0 --:--:-- --:--:-- --:--:-- 33744

$ docker-compose --version
docker-compose version 1.5.2, build 7240ff3
```

# docker-compose.yml を記述する
コンテナの定義情報を docker-compose.yml に記述します。ファイル名は何でもいいのですが、デフォルトの docker-compose.yml としておくと docker-composeの実行時にファイル名の指定が不要になります。

ファイルの内容は、docker run のパラメータとして指定しているものとほぼ同等です。

```:docker-compose.yml
samba:
  image: dperson/samba
  container_name: samba
  ports:
    - "139:139"
    - "445:445"
  volumes:
    - /mnt/pub:/mnt/pub
  command:
    "-s pub;/mnt/pub;no;no;no;foo -u foo;password"

unbound:
  image: unbound
  container_name: unbound
  tty: true
  ports:
    - "53:53"
    - "53:53/udp"
  command:
    "/start.sh"

minidlna:
  image: minidlna
  container_name: minidlna
  tty: true
  net: "host"
  ports:
    - "8200:8200"
    - "1900:1900/udp"
  volumes:
    - /mnt/pub:/mnt/pub
  command:
    "/start.sh"
```

理由(後述)があって ffmpeg のコンテナは記述しませんでした。

# docker-compose を実行してコンテナを作成・停止・削除する

docker-compose.yml が存在するディレクトリで docker-compose up を実行すると、コンテナが作成されます。-d はバックグラウンドで実行するオプションです。

```
$ docker-compose up -d
Creating minidlna
Creating samba
Creating unbound
```

docker-compose ps で状態が確認できます。普通にdocker psでもOKです。

```
$ docker-compose ps
      Name             Command             State              Ports
-------------------------------------------------------------------------
minidlna           /start.sh          Up
samba              samba.sh -s        Up                 0.0.0.0:139->139
                   pub;/mnt/pub;n                        /tcp, 0.0.0.0:44
                   ...                                   5->445/tcp
unbound            /start.sh          Up                 0.0.0.0:53->53/t
                                                         cp, 0.0.0.0:53->
                                                         53/udp
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                        NAMES
a7c8bcb0621a        unbound             "/start.sh"              About a minute ago   Up About a minute   0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp       unbound
f8e711a88ab4        dperson/samba       "samba.sh -s pub;/mnt"   About a minute ago   Up About a minute   0.0.0.0:139->139/tcp, 0.0.0.0:445->445/tcp   samba
cac99e2df5fd        minidlna            "/start.sh"              About a minute ago   Up About a minute                                                minidlna
```

docker-compose stop でコンテナの停止、docker-compose rm で削除ができます。-f は確認なしでコンテナを削除するオプションです。

```
$ docker-compose stop
Stopping unbound ... done
Stopping samba ... done
Stopping minidlna ... done

$ docker-compose rm -f
Going to remove unbound, samba, minidlna
Removing unbound ... done
Removing samba ... done
Removing minidlna ... done
```

run/stop/rmのあとに ラベルを指定することで、特定のコンテナを作成・停止・削除することもできます。

```
$ docker-compose stop minidlna
Stopping minidlna ... done
$ docker-compose up -d minidlna
Starting minidlna
```



docker run/stop/rmは コンテナの数だけ実行する必要があり、さらに run は複数あるパラメータを毎回正確に指定する必要があるのが面倒だったのですが、docker-composeのおかげで これらの課題が解決しました。



# docker-compose の制限事項???
docker run の -i (--interactive) に相当するオプションが、docker-composeには存在しないようです。従って、docker-composeで作成したコンテナに docker attach しても無反応で、シェルを呼び出すことができません。
ffmpegのコンテナのように、サービス目的ではなくシェルから使うことが前提のものは docker-composeを利用するべきではない、ということでしょうか。確かにこのようなコンテナは上げっぱなしにしておく意義が薄いので、素のdocker runで必要な都度作成するのがいいのかもしれません。

2016/1/18 追記
コメント欄でアドバイス頂きましたように、docker attachが使えずとも ```docker-compose run <ラベル> bash``` または ```docker exec -it <コンテナ> bash``` とすればシェルを呼び出せるとのことです。ご指摘ありがとうございます！


以上