Dockerのコンテナ間で通信したいとき、1つのComposeの場合は何もしなくてもお互いに通信が可能です。
デフォルトで Compose はアプリに対して1つの ネットワーク を作成します。サービス用の各コンテナはデフォルトのネットワークに接続し、そのネットワーク上で他のコンテナと相互に「 接続可能reachable 」になります。そして、コンテナ名と同じホスト名として、お互いが「 発見可能discoverable 」になります。
https://docs.docker.jp/compose/networking.html
例えば次のようなディレクトリ構成で、
└─ myapp
└─ docker-compose.yml
次のようなdocker-compose.yml の場合、web と mysql は「myapp_default」という同じネットワークに属するので、お互いに接続が可能です。
services:
web:
build: .
ports:
- "8000:8000"
db:
image: mysql:5.7
ports:
- "3306:3306"
では、別々に起動した Compose を通信したいときにはどうすればよいのでしょうか?
例えば、DBのコンテナを複数の アプリケーションのコンテナで共有したいとして、次のようなディレクトリ構成を考えます。
├─ db
│ └─ docker-compose.yml
├─ myapp1
│ └─ docker-compose.yml
└─ myapp2
└─ docker-compose.yml
それぞれの docker-compose.yml をいったん、次の通りに設定して実行してみます。
▼db/docker-compose.yml
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- "3306:3306"
▼myapp1/docker-compose.yml
services:
web:
build: .
ports:
- "8000:8000"
▼myapp2/docker-compose.yml
services:
web:
build: .
ports:
- "8001:8000"
この状態で、それぞれの Compose を起動するとそれぞれが別々のネットワークを作成してお互いを認識できないため、通信できません。
作成されたネットワークは「docker network ls」で確認できます。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
a4c505e8f4e3 bridge bridge local
bbe260c9a89d db_default bridge local → db のネットワーク
b15d22a5646c host host local
bbaf91ef68b0 myapp1_default bridge local → myapp1 のネットワーク
16beae3cd6ef myapp2_default bridge local → myapp2 のネットワーク
7f8dd4f9431b none null local
では、myapp1 と myapp2 を db のネットワークに追加して、お互いに通信できるようにします。
myapp1 と myapp2 の docker-compose.yml に networks の設定を追加します。
▼myapp1/docker-compose.yml
services:
web:
build: .
ports:
- "8000:8000"
networks:
- db_default
networks:
db_default:
external: true
▼myapp2/docker-compose.yml
services:
web:
build: .
ports:
- "8001:8000"
networks:
- db_default
networks:
db_default:
external: true
この状態でそれぞれのディレクトリの下で「docker-compose up -d」を実行してコンテナを更新します。
ネットワークコマンドを実行すると、myapp1_default、myapp2_default は使われていないネットワークとしてが削除されました。
$ docker network prune → 使用していないネットワークを削除
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
a4c505e8f4e3 bridge bridge local
6047fe4ba911 db_default bridge local
b15d22a5646c host host local
7f8dd4f9431b none null local
docker inspect コマンドでネットワークが共有されていることを確認します。
db_default ネットワークに myapp1-web-1、myapp1-web-2 コンテナも含まれていることがわかります。
これでmyapp1 と myapp2 から db への接続が可能になりました。
$ docker network inspect db_default
[
{
"Name": "db_default",
"Id": "bbe260c9a89d48f0243144a82512f01be8026cf2b6c37d7024687ab41480cc30",
"Created": "2024-03-27T07:23:14.507556133Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "192.168.80.0/20",
"Gateway": "192.168.80.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"1fff739dbf386a72e623a3013e73e94d59cc6b4385c813d196d814c08e009732": {
"Name": "myapp2-web-1",
"EndpointID": "83d3472fdf744b071adad15b9dcc07cfef250945937445011ffdd7930cd96639",
"MacAddress": "02:42:c0:a8:50:04",
"IPv4Address": "192.168.80.4/20",
"IPv6Address": ""
},
"98fe5931d98a32810abdecbb914441b97c3c7ab28dc95ae388b170721f15a4b5": {
"Name": "myapp1-web-1",
"EndpointID": "a98a7fee0d91ba111661b70138e245a99e473a337744912665ba847fa885c85e",
"MacAddress": "02:42:c0:a8:50:03",
"IPv4Address": "192.168.80.3/20",
"IPv6Address": ""
},
"b302d3d674ec68ff2c643cbcd485131eac1e050a0caa850973050bb3bd82dcfd": {
"Name": "db-db-1",
"EndpointID": "3c0c05727fd9aeb519f737cb3c64a680fa9ae8d4ee8c1ad18226ed9f49ba29d5",
"MacAddress": "02:42:c0:a8:50:02",
"IPv4Address": "192.168.80.2/20",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "db",
"com.docker.compose.version": "2.23.3"
}
}
]
おしまい。