🐳 Docker ネットワーク統合は面倒、ホストポートで「緊急」通信したい時

通常、コンテナ同士の通信には、共有ブリッジネットワークを作成し、サービス名(例: http://app-b:8080)で呼び出すのがセオリーです。しかし、時にはセオリー通りにはいかない「やむを得ない状況」に直面することもありますよね。

こんな「困った状況」ならこの方法を試してみてください

  • ホストに直接インストールされたサービスと通信したい時: DBやRedisがコンテナではなくホストOSに直接インストールされており、ネットワークを統合しようにもできない場合。
  • 他人が作成したコンテナで、ネットワーク設定を触るのが怖い時: 自分が管理していない複雑なネットワーク設定に、自分のコンテナを無理やり組み込んで障害が発生するのを恐れる場合。
  • ローカル開発中に「一時的」に接続だけ確認したい時: ネットワーク設計など関係なく、まずは今すぐホストポートに開いているサービスにリクエストが届くか確認する必要がある場合。

そんな時に役立つ裏技が、このhost.docker.internalです。

ホスト経由のコンテナ間通信


解決策:「コンテナの外の世界を見る窓」host.docker.internal

コンテナ内で127.0.0.1と呼び出しても、見えるのは自分自身(コンテナ)だけです。そこで、host.docker.internalという特殊なドメインを使用すると、コンテナの壁を越えてホストマシンのIPアドレスを見つけ出します。

Python (DRF) コード例:

# 'localhost'の代わりに'host.docker.internal'を使ってホストポートへアクセスします。
# App-Bがホストの8080ポートにバインドされている場合、以下のように呼び出します。
NEXTCLOUD_URL = "http://host.docker.internal:8080"

response = requests.get(NEXTCLOUD_URL)

⚠️ Linux ユーザーなら「手動設定」が必須です

Docker Desktop (Mac/Windows)ではこれがデフォルトで有効になっていますが、純粋なLinuxサーバーではDockerがこのドメインを自動的に設定してくれません。ビルド時や実行時に「このドメインはホストIPを指す」と明示的に指定する必要があります。

Docker Compose 設定例:

services:
  drf-app:
    image: my-drf-app-image
    extra_hosts:
      # host.docker.internalという名前でホストゲートウェイにアクセスするという宣言
      - "host.docker.internal:host-gateway"

常に最善策ではありません

改めて強調しますが、この方法は最終手段に近いものです。

  1. 最良の方法: 共有ブリッジネットワークを作成し、コンテナ名で通信する(セキュリティ上最も安全)。
  2. この方法を使う理由: ホストに直接起動したプロセスにアクセスする必要がある場合や、ネットワーク構造をどうしても統合できない「孤立した」環境である場合。

困った時に役立つこの「緊急脱出方法」は、セオリーが使えない場合の切り札としてのみ活用してください!