Carpe Diem

備忘録

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

概要

単一ホスト上で複数のコンテナを起動するときはDocker Composeを使うのが便利です。
今回はその基本的な使い方を紹介します。

環境

  • Docker 1.11.0
  • Docker-Compose 1.7.0

Docker Composeのメリット

  • 複数コンテナを管理しやすい
  • スケールアウト、スケールインが簡単

設定

docker-compose.yml

version: '2'
services:
  nginx:
    image: nginx
    ports:
      - "80"
  mongodb:
    image: mongo
    container_name: mongo
    volumes:
      - /data/db
    ports:
      - "27017:27017"
  redis:
    image: redis
    container_name: redis
    ports:
      - "6379:6379"

設定詳細

項目 説明
version バージョン。2が新しい
services 起動するコンテナを定義していく
image dockerイメージ
container_name コンテナ名。こちらはユニークである必要があるため設定するとスケールできなくなる
ports 公開するポート。<コンテナ側>のみで設定するか、<ホスト側>:<コンテナ側>で設定
volumes Docker Volume

動作確認

起動

$ docker-compose -f docker-compose.yml up -d

-dをつけるとバックグラウンドで実行してくれます。

確認してみます。

確認

$ docker-compose ps
     Name                   Command               State              Ports            
-------------------------------------------------------------------------------------
hostname_nginx_1   nginx -g daemon off;             Up      443/tcp, 0.0.0.0:80->80/tcp 
mongo            /entrypoint.sh mongod            Up      0.0.0.0:27017->27017/tcp    
redis            docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp 

各コンテナがきちんと起動しています。

ログ

長いので省略しますがredisの起動ログなどが表示されます。

$ docker-compose logs
Attaching to redis, hostname_nginx_1, mongo
redis      | 1:C 08 May 15:14:19.649 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis      |                 _._                                                  
redis      |            _.-``__ ''-._                                             
redis      |       _.-``    `.  `_.  ''-._           Redis 3.0.7 (00000000/0) 64 bit
redis      |   .-`` .-```.  ```\/    _.,_ ''-._                                   
redis      |  (    '      ,       .-`  | `,    )     Running in standalone mode
redis      |  |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
redis      |  |    `-._   `._    /     _.-'    |     PID: 1
redis      |   `-._    `-._  `-./  _.-'    _.-'                                   
redis      |  |`-._`-._    `-.__.-'    _.-'_.-'|                                  
redis      |  |    `-._`-._        _.-'_.-'    |           http://redis.io        
redis      |   `-._    `-._`-.__.-'_.-'    _.-'                                   
redis      |  |`-._`-._    `-.__.-'    _.-'_.-'|                                  
redis      |  |    `-._`-._        _.-'_.-'    |                                  
redis      |   `-._    `-._`-.__.-'_.-'    _.-'                                   
redis      |       `-._    `-.__.-'    _.-'                                       
redis      |           `-._        _.-'                                           
redis      |               `-.__.-'                                               
redis      | 

疎通

docker 1.10.0から内部DNSサーバが立つようになったので、linkオプションを使わなくてもコンテナ名で疎通ができるようになりました。
コンテナ間で疎通ができているかを確認します。

$ docker exec -it redis /bin/bash
root@6703870b0a9a:/# ping mongo 
PING mongo (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.185 ms
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.095 ms

大丈夫ですね。

停止

1つだけ停止したいときはサービス名を指定します。コンテナ名ではないので注意。

$ docker-compose stop redis
Stopping redis ... done

全部停止したいときは何も指定せず実行します。

$ docker-compose stop
Stopping redis ... done
Stopping hostname_nginx_1 ... done
Stopping mongo ... done

削除

1つだけ削除したいときはコンテナを指定します。

$ docker-compose rm redis

全部停止したいときは何も指定せず or --allをつけて実行します。

$ docker-compose rm

スケールアウト、スケールイン

スケールアウトさせます。

$ docker-compose scale nginx=3
Creating and starting hostname_nginx_2 ... done
Creating and starting hostname_nginx_3 ... done

スケールインさせます。

$ docker-compose scale nginx=1
Stopping and removing hostname_nginx_2 ... done
Stopping and removing hostname_nginx_3 ... done

ホスト側のポートが1つに固定されているとエラーが出ます。この場合死にコンテナとして生成されるので忘れず削除してください。

$ docker-compose scale nginx=3
WARNING: The "nginx" service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash.
Creating and starting hostname_nginx_2 ... error
Creating and starting hostname_nginx_3 ... error

ERROR: for hostname_nginx_3  driver failed programming external connectivity on endpoint hostname_nginx_3 (4031152d5ec0522076f199a4fec8419447e11e86838bfc9ddb446dacdd1bfb85): Bind for 0.0.0.0:80 failed: port is already allocated

ERROR: for hostname_nginx_2  driver failed programming external connectivity on endpoint hostname_nginx_2 (abb0696e2fafb5772228495b890b2e0ba755d4564581ce829e5dfca877535dbf): Bind for 0.0.0.0:80 failed: port is already allocated

ソース