別々のdocker-compose環境同士でネットワーク間を連携する
リポジトリを別々に分けていて、それぞれのリポジトリにdocker-compose.ymlがある場合が多いと思います。
それぞれでdocker-composeを立ち上げれば、当然異なるdockerネットワークとなります。
しかし、場合によっては以下の画像のように、その2つのdockerネットワーク間で通信をしたい場合もあると思います。
フロントエンドとバックエンドでリポジトリを分け、それぞれのコンテナ間でAPI通信をするためにも、フロントエンドからバックエンドにHTTPリクエストを送れるようにしなければいけません。
外向きの通信をするコンテナに対して新たなネットワークを設定
今回はフロントエンドからバックエンドに対してHTTPリクエストを送るようにします。
今回はexternal
というネットワークを作成して設定します。docker-compose.yml
の一番下に以下を記述します。
networks:
external:
external: true
コンテナ側のnetworks
に繋ぐネットワークを記述します。ここでは新たに作成したネットワークのexternal
を記述します。
version: '3'
services:
front:
build: .
ports:
- '3000:3000'
networks:
- external
.....
.....
networks:
external:
external: true
バックエンド側にも外向きのネットワークを接続を設定
次に通信を受けるバックエンド側にも外向きのネットワークを接続します。
これによりフロントエンド側からの通信を受け取ることができます。
バックエンドのコンテナにも先程作成したexternal
を記述します。
version: '3'
services:
backend:
....
build: .
ports:
- '8000:8000'
networks:
- external
.....
.....
# 以下も追加する
networks:
external:
external: true
Dockerネットワークを作成する
以下のコマンドでdockerネットワークを作成できます。
$ docker network create external
external
ネットワークが作成されたかどうかは以下で確認できます。externalネットワークが表示されれば、作成は成功です。
$ docker network ls|grep external
{container_id} external bridge local
Dockerネットワークを確認する
次に実際に作成したexternal
ネットワークにコンテナが繋がっているかを確認します。
$ cd repository_1
$ docker-compose up -d
$ cd repository_2
$ docker-compose up -d
docker network inspect
コマンドで、Dockerネットワークの詳細が表示されます。
以下のコマンドでexternal
ネットワークに上記2つのbackendとfrontendのコンテナがあれば成功です。
$ docker network inspect external
[
{
"Name": "external",
....
"Containers": {
# フロント側のコンテナ
"408e6429979bd18ee5719e3589440a8c1cc8df2b15f634642bf7779e6ca8a9a9": {
"Name": "frontend",
"EndpointID": "a018492ee2fd5d7465cbccc850b7a9e5ad943f11188ab94d4db14503e33e7d91",
"MacAddress": "02:42:ac:17:00:02",
"IPv4Address": "172.23.0.2/16",
"IPv6Address": ""
},
# バックエンド側のコンテナ
"946f9de7a422c66a7b39536ceef592826fb3d21e5f80dd2ad3048eb1ac1263aa": {
"Name": "backend",
"EndpointID": "9379f10d542cf723f800e998cc3f7ba72765006bcff7b3474da7525f0b96f4f0",
"MacAddress": "02:42:ac:17:00:03",
"IPv4Address": "172.23.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
externalネットワークのfrontendコンテナのIPアドレスが172.23.0.2
、backendコンテナIPアドレスが172.23.0.3
だということがわかります。
- frontend: 172.23.0.2
- backend: 172.23.0.3
ネットワークアドレスが172.23.0.0
のネットワークだということもわかります。
コンテナ間で疎通確認を行う
次に実際にフロントエンドからバックエンド側に対して通信が行えるかを確認してみます。
上記で確認したbackendコンテナのIPは172.23.0.3
です。このIPアドレスに対してpingを送ってみます。
$ cd repository_1
$ docker-compose exec frontend ping 172.23.0.3
PING 172.23.0.3 (172.23.0.3) 56(84) bytes of data.
64 bytes from 172.23.0.3: icmp_seq=1 ttl=64 time=0.076 ms
64 bytes from 172.23.0.3: icmp_seq=2 ttl=64 time=0.071 ms
64 bytes from 172.23.0.3: icmp_seq=3 ttl=64 time=0.103 ms
64 bytes from 172.23.0.3: icmp_seq=3 ttl=64 time=0.099 ms
pingの結果が返ってくれば成功です。
externalネットワーク内でコンテナのIPアドレスを固定する
docker network inspect
で毎回IPアドレスを調べるのは面倒です。
そこで、コンテナに対して割り振られるIPアドレスを固定することができます。
次のコマンドでサブネットマスクとゲートウェイを固定したDockerネットワークを作成できます。
ここではネットワークアドレスを192.168.1.0/24
、ゲートウェイを192.168.1.1
に設定します。
### subnet, gatewayを指定する
$ docker network create external-api --subnet=192.168.1.0/24 --gateway=192.168.1.1
次にdocker-compose.yml
に以下を記述することで、任意のIPアドレスをコンテナに割り振ることができます。
networks:
# 任意のIPアドレスを設定する
- external:
ipv4_address: 192.168.1.2
ファイル全体では以下のようになります。
version: '3'
services:
front:
build: .
ports:
- '3000:3000'
networks:
# 任意のIPアドレスを設定する
- external:
ipv4_address: 192.168.1.2
.....
.....
networks:
external:
external: true
バックエンド側にもコンテナにIPアドレスを割り振ります。
version: '3'
services:
backend:
....
build: .
ports:
- '8000:8000'
networks:
- external:
ipv4_address: 192.168.1.3
.....
.....
# 以下も追加する
networks:
external:
external: true
docker network inspect
コマンドで確認してみると、先程指定した任意のIPアドレスがコンテナに割り振られていることがわかります。
$ docker network inspect external
[
{
"Name": "external",
....
"Containers": {
# フロント側のコンテナ
"408e6429979bd18ee5719e3589440a8c1cc8df2b15f634642bf7779e6ca8a9a9": {
"Name": "frontend",
"EndpointID": "a018492ee2fd5d7465cbccc850b7a9e5ad943f11188ab94d4db14503e33e7d91",
"MacAddress": "02:42:ac:17:00:02",
"IPv4Address": "192.168.1.2/24",
"IPv6Address": ""
},
# バックエンド側のコンテナ
"946f9de7a422c66a7b39536ceef592826fb3d21e5f80dd2ad3048eb1ac1263aa": {
"Name": "backend",
"EndpointID": "9379f10d542cf723f800e998cc3f7ba72765006bcff7b3474da7525f0b96f4f0",
"MacAddress": "02:42:ac:17:00:03",
"IPv4Address": "192.168.1.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
Discussion
こちらの部分ですが、networks:の部分こうではないでしょうか?
(ハイフンを消しました)