Dockerでコンテナ間通信を行う方法
はじめに
今回はheadless構成でDockerを用いてプロジェクト作成していた際にフロント(Next.jsのフロントサーバー)とバックエンドとで上手く通信が出来なかったので、その解消方法をご紹介します。
Dockerのコンテナ間通信
前提
前提として、今回はdocker-composeを使用してます。
コンテナ間通信
まず、docker ps
を実行することで、下記の情報が得られます。
- Container ID
- Docker Image
- Command
- Created
- Status
- Ports
- Names
実際にdocker ps
した結果の一例
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d2d41cb845cb mysql:8.0 "docker-entrypoint.s…" 6 hours ago Up 6 hours 0.0.0.0:3306->3306/tcp, 33060/tcp database
7ffb48d09e69 onstep_web "docker-php-entrypoi…" 6 hours ago Up 6 hours 0.0.0.0:80->80/tcp web
842c6d63a6c0 phpmyadmin/phpmyadmin "/docker-entrypoint.…" 6 hours ago Up 6 hours 0.0.0.0:4040->80/tcp phpmyadmin
61aa6b282b2a vsc-onstep-demo-spa-react-24dc1f989a89aee055f0571b654bb80a-features "/bin/sh -c 'echo Co…" 2 weeks ago Up 6 hours vigilant_allen
ここで得た情報から下記を用いてcontainer間通信を行うことが可能です。
- Container ID
- Container名 (NAMES)
設定例
Container ID
Container名
※ 紹介はしていますが、Container IDに関しては毎回固定の値を取得する訳ではないので、極力使用しないようにしましょう。
また、docker inspect ${Container名}
を実行すると、Containerの詳細が確認でき、
Networks項目にて、今そのContainerがどこのネットワークに属しているのかや、通信を行う際の接続情報等が取得できます。(今回関係のない項目については説明を省きます。)
下記はNetworks内のみ抜粋ですが、下記のようなデータが取得できます。
"Networks": {
"onstep-demo-network": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"web",
"web",
"7ffb48d09e69"
],
"NetworkID": "5b36f627d0ed385ddb350c127dfc8e4d81466d9171f09bc9b2b86b26ce7ba378",
"EndpointID": "d505803ae8e2c1b4be1518b14b5365eb1db3f238178264409594e8bb088301cb",
"Gateway": "172.26.0.1",
"IPAddress": "172.26.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:1a:00:04",
"DriverOpts": null
}
}
ここで登場するAliases(別名)を利用して同network内でコンテナ間通信を行えます。
設定例
Container ID
Container名・Service名
先に接続方法をご紹介しましたが、docker-compose.yml内で下記のようにして名称を設定出来ます。
docker-compose
services:
app: ← service名を指定する
build: ./
container_name: onstep-demo ← Container名を指定する
hostname: onstep-host ← host名を指定する
volumes:
- ./app:/usr/app
command: sh -c "yarn start"
ports:
- "3000:3000"
ここで設定した情報のうち下記を用いて接続先を指定することができます。
- service名
- container名
- host名
異なるネットワーク内のコンテナ間通信
ここまで、コンテナ間での通信を行う方法について説明してきましたが、
今回は、補足として異なるネットワーク内のコンテナ間で通信を行う場合の通信方法を説明します。
簡単に言ってしまうと、同じネットワーク内に入れてあげれば今回説明した通信方法で接続を行うことが可能です。
まず、新規でnetworkを作成しましょう。
docker network create -d bridge ${network名}
続いてdocker-compose内でnetwork設定をします。
因みにnetworkはdocker-compose内で一括設定することも個別に設定することもどちらも可能です。
services:
app:
build: ./
container_name: onstep-demo
volumes:
- ./app:/usr/app
command: sh -c "yarn start"
ports:
- "3000:3000"
networks: ←どのnetworkに入れるか指定する。
- onstep-demo-network
networks: ←networkの接続先の設定を行う。
onstep-demo-network: ←複数記載することで、networkを複数設定できる。
external: true ←既存のネットワークへの接続を行う。
もしくは下記も利用可能です。
services:
app:
build: ./
container_name: onstep-demo
volumes:
- ./app:/usr/app
command: sh -c "yarn start"
ports:
- "3000:3000"
networks:
- onstep-demo-network
networks:
default:
name: onstep-demo-network
driver: onstep-demo-network
external: true
下記は公式より転用ですが、networksに複数networkを記載し、networkを分けることも可能です。
services:
proxy:
build: ./proxy
networks:
- frontend
app:
build: ./app
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
# Use a custom driver
driver: custom-driver-1
backend:
# Use a custom driver which takes special options
driver: custom-driver-2
driver_opts:
foo: "1"
また、指定したnetwork内に正しく入っているかもdocker inspect
を利用して確認することが出来ます。
今回はnetworkの確認なので、network名を指定します。
docker inspect ${network名}
下記も抜粋ですが、こんな感じでnetwork内に入っているContaiersを確認することが出来ます。
同じnetwork内に入れ込むことが出来ていれば設定完了です。
"Containers": {
"7ffb48d09e691d4c9c211a5bf085b1cbcee2fbe44221e422cc8579c018d01803": {
"Name": "web",
"EndpointID": "d505803ae8e2c1b4be1518b14b5365eb1db3f238178264409594e8bb088301cb",
"MacAddress": "02:42:ac:1a:00:04",
"IPv4Address": "172.26.0.4/16",
"IPv6Address": ""
},
"842c6d63a6c073aaeacb352b2fd4a9a294a39a9a0f6b8466074593ecd089fe79": {
"Name": "phpmyadmin",
"EndpointID": "81b12fe31d75773a90c15171490bbdce7ed2f76bd7ec33d83582d6c7f2950755",
"MacAddress": "02:42:ac:1a:00:02",
"IPv4Address": "172.26.0.2/16",
"IPv6Address": ""
},
"d2d41cb845cbda424411309501812268b169fba07f13153c0474474ce84c9dff": {
"Name": "database",
"EndpointID": "3dffdb568be1b7af0f7cc3aab45dba82b283d93cd8aea115103bf39f7e4f5f73",
"MacAddress": "02:42:ac:1a:00:03",
"IPv4Address": "172.26.0.3/16",
"IPv6Address": ""
},
"db7b27b3cd64e48e25478fc8e4236e94e702ad628a554df9a086d8af6b1a2d40": {
"Name": "onstep-demo",
"EndpointID": "0e072a8787907e26c62bb0909339646c42c4640b12c534fca482e316a0fa8fde",
"MacAddress": "02:42:ac:1a:00:05",
"IPv4Address": "172.26.0.5/16",
"IPv6Address": ""
}
後は先に説明したのと同じように接続先を設定することでコンテナ間の通信を行うことが出来ます。
補足:docker-compose.ymlに変更を加えた場合
今回の記事を通してdocker-compose.ymlに変更を加えた場合、一度止めて、docker-composeを再起動させる必要がありますので、変更を加えた場合は再起動するようにしましょう。
まとめ
今回はdocker composeでコンテナ間通信を行う方法についてご説明いたしました。
docker compose自体は意外と簡単に設定出来ますので、手軽に色んな設定を試してみていただければなと思います。
ここまで読んでいただきありがとうございました。
Discussion