docker-compose を複数起動する

docker-composeとは?

docker-composeは複数のコンテナを手軽に扱うためのツール。

yml形式でコンテナに関する設定ができ、

sample]$  ls
docker-compose.yml

docker-compose.yml

version: "3"
services:
    ap:
        image: "centos:7"
        command: ["tail","-f","/dev/null"]
        depends_on:
            - "db"
    db:
        image: 'centos:7'
        command: ["tail","-f","/dev/null"]

up コマンドでコンテナが起動できる。

$ docker-compose up -d
Creating network "sample_default" with the default driver
Creating sample_db_1 ... done
Creating sample_ap_1 ... done
$ docker-compose ps
   Name            Command        State   Ports
-----------------------------------------------
sample_ap_1   tail -f /dev/null   Up
sample_db_1   tail -f /dev/null   Up

コンテナは ディレクトリ名_default というネットワークに接続され、

sample]$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
93a567afe736        bridge              bridge              local
2c4c563287d8        docker_default      bridge              local
a5db6a546224        host                host                local
d1e8a752607e        none                null                local
92ae5876b85a        sample_default      bridge              local
sample]$ docker inspect sample_ap_1
...
            "Networks": {
                "sample_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "56536b1e4436",
                        "ap"
                    ],
...

コンテナ間は /etc/hosts に設定されたサービス名でアクセスできる。

$ docker exec -it sample_ap_1 ping db
PING db (172.19.0.2) 56(84) bytes of data.
64 bytes from sample_db_1.sample_default (172.19.0.2): icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from sample_db_1.sample_default (172.19.0.2): icmp_seq=2 ttl=64 time=0.102 ms

コンテナを複数起動する場合は --scale オプションを利用する。

sample]$ docker-compose up -d --scale ap=1 --scale db=2
Starting sample_db_1 ... done
Creating sample_db_2 ... done
sample_ap_1 is up-to-date
sample]$ docker-compose ps
   Name            Command        State   Ports
-----------------------------------------------
sample_ap_1   tail -f /dev/null   Up
sample_db_1   tail -f /dev/null   Up
sample_db_2   tail -f /dev/null   Up

図にするとこんな感じ。

f:id:kimulla:20191201210823p:plain

課題

--scale オプションでコンテナを複数起動すると、コンテナ間のリンクがどのように張られるかわからない。以下の実行結果だと、sample_ap_1とsample_ap_2がどちらもsample_db_1に接続されてしまっている。ビルドやテストをdocker-compose上で複数実行したい場合、APが意図せず同じDBを参照してしまって問題が起きる。

sample]$ docker-compose up -d --scale ap=2 --scale db=2
sample_db_1 is up-to-date
sample_db_2 is up-to-date
Starting sample_ap_1 ... done
Creating sample_ap_2 ... done
sample]$ docker exec -it sample_ap_1 ping db
PING db (172.19.0.3) 56(84) bytes of data.
64 bytes from sample_db_1.sample_default (172.19.0.3): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from sample_db_1.sample_default (172.19.0.3): icmp_seq=2 ttl=64 time=0.100 ms
^C
--- db ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.044/0.072/0.100/0.028 ms
[kimura@localhost sample]$ docker exec -it sample_ap_2 ping db
PING db (172.19.0.3) 56(84) bytes of data.
64 bytes from sample_db_1.sample_default (172.19.0.3): icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from sample_db_1.sample_default (172.19.0.3): icmp_seq=2 ttl=64 time=0.096 ms
^C

検証環境

$ docker -v
Docker version 18.03.1-ce, build 9ee9f40
$ docker-compose -v
docker-compose version 1.21.2, build a133471

解決方法

上記を実現するためには、 -p オプションを利用する。図にすると以下のイメージ。

f:id:kimulla:20191201210937p:plain

sample]$ $ docker-compose up -d
Stopping and removing sample_db_2 ... done
Starting sample_db_1              ... done
Stopping and removing sample_ap_2 ... done
Starting sample_ap_1              ... done
sample]$docker-compose -p other up -d
Creating network "other_default" with the default driver
Creating other_db_1 ... done
Creating other_ap_1 ... done
sample]$ docker ps
CONTAINER ID        IMAGE               COMMAND               CREATED              STATUS              PORTS               NAMES
65c43c190f0e        centos:7            "tail -f /dev/null"   About a minute ago   Up About a minute                       other_ap_1
e441cf9d6a60        centos:7            "tail -f /dev/null"   About a minute ago   Up About a minute                       other_db_1
56536b1e4436        centos:7            "tail -f /dev/null"   8 minutes ago        Up 8 minutes                            sample_ap_1
3f8635959fef        centos:7            "tail -f /dev/null"   8 minutes ago        Up 8 minutes                            sample_db_1
sample]$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
...
b17d46efb9b8        other_default       bridge              local
92ae5876b85a        sample_default      bridge              local

これで独立したdocker-composeの環境を用意できる。