ローカル環境の異なるDocker Compose間の通信をhost.docker.internalで解決する

インフラ

externalなDockerネットワークを共有することで、異なるDokcer環境でもコンテナ間の通信ができます。
Dockerネットワークを利用したコンテナの通信方法の詳細はDockerネットワークとコンテナ名で実現する複数Docker Compose間の接続方法で紹介しました。

ローカル環境においては、Dockerネットワークを構築せずとも異なるDocker環境間で通信ができます。
今回はローカル環境における異なるDocker環境の通信方法について紹介します。

結論: host.docker.internalでローカル環境を経由して異なるDocker環境へアクセスする

host.docker.internalとはDocker Desktopで用意されている、コンテナからローカル環境を参照する際のホスト名です。

過去にはdocker.for.mac.localhostdocker.for.mac.host.internalでローカル環境に接続できていましたが、Docker Desktop 4.3.0でそれらのホスト名は非推奨および削除予定とされています。1

host.docker.internalでローカル環境を参照し、接続対象のコンテナがローカル環境に開放しているポートでアクセスすれば異なるDocker環境でも通信ができます。

具体例について

以下のようにフロントエンドとバックエンドで異なるDocker Composeを用意していたとします。

frontend/docker-compose.yml

version: '3'
  services:
    web:
(略)

backend/docker-compose.yml

version: '3'
  api:
    ports:
      - '3001:3000'
(略)

このとき、フロントエンドのwebコンテナからバックエンドのapiコンテナにはhttp://host.docker.internal:3001で接続できます。
3001apiコンテナと接続しているローカル環境のポートです。

参考: 接続先がRailsの場合はhost.docker.internalによるアクセス許可を設定する

Rails 6以降2、DNSリバインディング攻撃からの保護のためデフォルトでは.localhost0.0.0.0::からのアクセスのみ許可されています。

ですので、設定ファイルにconfig.hosts << "host.docker.internal"config.hosts.clearを追加してhost.docker.internalでコンテナにアクセスできるように設定する必要があります。
設定をしないと[ActionDispatch::HostAuthorization::DefaultResponseApp] Blocked host: host.docker.internalというエラーが発生します。

詳細解説はlocalhost以外のホスト名でローカル環境のRailsに接続する方法で紹介しています。

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!

参考資料