Dock Stay
コンテナからホストを参照する - host.docker.internal の使い方・オプション・サンプル

コンテナからホストを参照する - host.docker.internal

コンテナから「ホスト側の localhost」に繋ぎたいときに使う特殊名。Docker Desktop では最初から解決できるが、Linux では `--add-host=host.docker.internal:host-gateway` を付ける必要がある。

概念図

host.docker.internal diagram

構文

bash
docker run --add-host=host.docker.internal:host-gateway <image>

実例

コンテナからホストの 5432 ポートにアクセス

bash
# Docker Desktop: そのまま動く / works out of the box
docker run --rm curlimages/curl \
  curl -v http://host.docker.internal:5432

# Linux: host-gateway の明示が必要 / must add host-gateway on Linux
docker run --rm \
  --add-host=host.docker.internal:host-gateway \
  curlimages/curl curl -v http://host.docker.internal:5432

compose.yml で host-gateway を OS 横断で設定する

bash
services:
  api:
    image: myorg/api
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      DATABASE_URL: postgres://host.docker.internal:5432/app

Docker Desktop では使える

Docker Desktop(macOS / Windows)では、host.docker.internal という特殊な DNS 名が最初から有効になっており、コンテナ内部から参照すると「ホスト OS 側」に解決される。

たとえば macOS の開発 PC で直接起動している Postgres(localhost:5432)に、コンテナの中から host.docker.internal:5432 で接続できる。

これは Desktop が裏で走らせている軽量 VM が、VM ↔ ホスト間の特別なブリッジを用意しているために成立している仕組み。

IDE や開発ツールをホスト側で動かしつつ、一部のサービスだけコンテナ化する構成でよく使われる。

Linux では `--add-host=host.docker.internal:host-gateway`

Linux の素の Docker Engine には host.docker.internal の事前設定が無く、何もしないと名前解決に失敗する。

解決には docker run 時に --add-host=host.docker.internal:host-gateway を指定する。

host-gateway は Docker 20.10 以降で追加された特別な識別子で、コンテナから見たホストの IP(通常は Docker ブリッジのゲートウェイ)に自動で置き換えられる。

Compose の場合は各サービスに extra_hosts: ["host.docker.internal:host-gateway"] を書いておけば OS を問わず同じ挙動になる。

この一行をテンプレに入れておくと、Docker Desktop 前提で書かれた設定が Linux CI でも動くようになる。

bash
docker run --rm \
  --add-host=host.docker.internal:host-gateway \
  alpine sh -c "getent hosts host.docker.internal"

なぜこの差があるのか

Docker Desktop は macOS や Windows の上で Linux コンテナを動かすために、裏側で常に軽量 Linux VM を動かしている。

この VM とホスト OS を繋ぐ特別なネットワーク経路が必要で、その終端に分かりやすい名前として host.docker.internal が予約されてきた経緯がある。

一方、Linux ネイティブ環境ではコンテナとホストが同じカーネルで動くため、ブリッジのゲートウェイ IP さえ分かれば通信自体はできるが、その IP はネットワーク構成で変わる。

そこで「動的に解決してくれるエイリアス」が必要となり、host-gateway による --add-host という明示オプションが後付けで整備された。

結果として、同じ名前でも「標準装備」の Desktop と「手で有効化」の Linux という差が残っている。

関連トピック