docker-compose up 時にポート指定してもコンテナ内のデフォルト設定も上書きしないと意味ない

複数のプロジェクトを同時並行で開発している時、ローカルの Docker 環境のポートがかち合うことってよくあると思います。こういう時は素直に片方のコンテナを docker-compose stop で一旦止めてから docker-compose up し直すのも手ですね。めんどいですね。

そんな時は docker-compose.yml でかち合わない port を指定してあげればうまくいきます。うまくいくんですけど、実際にコンテナ内に入って MySQL やら Redis につなごうとするとなんかポート番号が合わないんですよ。

例えばこんな docker-compose.yml があったとします(かなり省略してます)。

version: '3'
services:
  redis:
    ports:
      - '6380:6380'
  mysql:
    ports:
      - '3307:3307'

この時、ポートフォワーディング的にはこんな感じになってるはずです。

$ docker ps --format "table {{.Ports}}"
PORTS
3306/tcp, 0.0.0.0:3307->3307/tcp
6379/tcp, 0.0.0.0:6380->6380/tcp

なんで 3306/tcp と 6379/tcp が健在なのか皆目見当もついてないですが一旦置いておきます。

とにかく、 app コンテナに入って mysql もしくは redis コンテナにつなごうとするとエラーが起きます。

mysql コンテナの場合、

root@5315917581ee:/app# mysql -h mysql -P 3307 -p
Enter password:
ERROR 2003 (HY000): Can't connect to MySQL server on 'mysql' (111)

redis コンテナの場合、

root@5315917581ee:/app# redis-cli -h redis -p 6380
Could not connect to Redis at redis:6380: Connection refused
not connected>

こんな感じに指定したポートで入ろうとしても拒否されてしまいます。なんでやねん。

どうやら docker-compose up でコンテナ立ち上げ時に command キーの値でポート指定してあげないといけないっぽいですね。なので、正しくはこんな感じになります。

version: '3'
services:
  redis:
    ports:
      - '6380:6380'
    command: --port 6380
  mysql:
    ports:
      - '3307:3307'
    command: --port 3307

こうすれば ports で指定した番号で接続できるようになります。なるんですけど、ここまですると initializers/redis.rb のポート設定やら config/database.yml のポート設定やらまでいじらないといけないので、そこまで統一するメリットあるんかいなと思えてきます。コンテナ立ち上げ時のポートフォワーディングと実際のクライアント立ち上げ時のポート指定って違う概念(なのかまで確証取れてない)なんだなって思いました。ここもうちょっと理解度深めたいなあ…。