理系学生日記

おまえはいつまで学生気分なのか

Docker Composeのscaleオプションを使ったときのポートマッピング設定方法

Docker Compose は便利で、--scale オプションを使えば複数コンテナを並べることも簡単です(Docker Swarm とか使えばまた別の方法がありますが)。

一方で、ポートマッピングを行っている設定において --scale オプションを使っているとき、 ポート重複により起動に失敗してしまいます。

version: '3'
services:
  web:
    image: nginx:1.15
    ports:
      - 8000:80
$ docker-compose up -d --scale web=3
WARNING: The "web" service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash.
Starting nginx_web_2 ... error
Starting nginx_web_3 ... error

ERROR: for nginx_web_3  Cannot start service web: driver failed programming external connectivity on endpoint nginx_web_3 (45d4855404c12badae67aa98f7115577784b1bcd039360625733293afb467fba): Bind for 0.0.0.0:8000 failed: port is already allocated
(snip)
ERROR: Encountered errors while bringing up the project.

じゃぁこういうときどうすれば良いんじゃ、ってことですが、ローカルのポートの設定をレンジ指定すれば良いです。 以下が設定変更前後の差分。

$ diff -u docker-compose.yaml{.orig,}
--- docker-compose.yaml.orig    2018-06-15 22:21:34.000000000 +0900
+++ docker-compose.yaml 2018-06-15 22:27:15.000000000 +0900
@@ -3,4 +3,4 @@
   web:
     image: nginx:1.15
     ports:
-      - 8000:80
+      - 8000-8002:80

このように設定して立ち上げると、以下のように 800[0-2] ポートに割り振られるようになります。

$ docker-compose port --index=1 web 80
0.0.0.0:8002
$ docker-compose port --index=2 web 80
0.0.0.0:8001
$ docker-compose port --index=3 web 80
0.0.0.0:8000