💨

Dockerでコンテナ間通信を行う方法

2022/12/02に公開

はじめに

今回は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