title: “Dockerコンテナからlocalhostに接続できない” date: 2026-01-16 draft: true description: “Dockerコンテナ内からlocalhostやホストマシンのサービスに接続できない場合の確認手順と対処法を解説” categories: [“runbook”] tags: [“runbook”, “docker”, “localhost”, “ネットワーク”, “接続エラー”, “host.docker.internal”]

症状

Dockerコンテナ内から localhost127.0.0.1 に接続しようとすると、接続が拒否される・タイムアウトする

結論:まずこれを確認

  1. コンテナ内の localhost はコンテナ自身を指す(ホストマシンではない)
  2. ホストマシンに接続するには host.docker.internal を使用する
  3. Linux環境では --add-host オプションが必要な場合がある

トラブルシューティングフロー

    flowchart TD
    A[コンテナからlocalhostに接続できない] --> B{接続先はどこ?}
    B -->|ホストマシン上のサービス| C[host.docker.internal を使用]
    B -->|別のコンテナ| D[同一ネットワークに参加]
    B -->|コンテナ自身| E[localhost/127.0.0.1 で正しい]
    C --> F{OSは?}
    F -->|macOS/Windows| G[そのまま使用可能]
    F -->|Linux| H[--add-host オプションを追加]
    D --> I[docker network で確認]
    E --> J[サービスが起動しているか確認]
  

よくある原因

  • localhostの誤解 - コンテナ内のlocalhostはコンテナ自身を指す
  • ネットワークモードの問題 - bridgeモードではホストと分離される
  • host.docker.internalの未設定 - Linux環境では自動設定されない
  • ファイアウォールのブロック - ホスト側でDockerからの接続を拒否している
  • サービス未起動 - 接続先のサービスがそもそも起動していない
  • ポートのバインドアドレス - サービスが127.0.0.1のみでリッスンしている
  • Docker Composeのネットワーク設定 - サービス間通信の設定ミス

確認手順

ステップ1: 接続先を明確にする

まず、何に接続しようとしているか確認する。

    # コンテナ内で実行
curl -v localhost:8080
  

🔍 チェックポイント: エラーメッセージが Connection refusedConnection timed out かを確認

ステップ2: ホストマシンへの接続(macOS/Windows)

macOSまたはWindowsの場合、host.docker.internal を使用する。

    # コンテナ内で実行
curl -v host.docker.internal:8080
  

🔍 チェックポイント: host.docker.internal が名前解決できれば正常

ステップ3: ホストマシンへの接続(Linux)

Linuxでは --add-host オプションを追加してコンテナを起動する。

    # コンテナ起動時
docker run --add-host=host.docker.internal:host-gateway your-image
  

Docker Composeの場合:

    services:
  app:
    image: your-image
    extra_hosts:
      - "host.docker.internal:host-gateway"
  

🔍 チェックポイント: コンテナ内で ping host.docker.internal が応答すれば設定完了

ステップ4: ホストネットワークモードを使用する

ホストのネットワークスタックを直接使用する方法。

    docker run --network host your-image
  

🔍 チェックポイント: この場合 localhost がホストマシンを指す

⚠️ 注意: --network host はmacOS/Windowsでは期待通り動作しない

ステップ5: コンテナ間通信の確認

別のコンテナに接続する場合は、同一ネットワークに参加させる。

    # ネットワーク作成
docker network create my-network

# コンテナをネットワークに接続
docker run --network my-network --name container-a image-a
docker run --network my-network --name container-b image-b
  
    # container-b から container-a に接続
curl http://container-a:8080
  

🔍 チェックポイント: コンテナ名で名前解決できれば正常

ステップ6: ホスト側サービスのバインドアドレス確認

ホストのサービスが 127.0.0.1 のみでリッスンしている場合、Dockerからアクセスできない。

    # ホストで実行
netstat -tlnp | grep 8080
# または
ss -tlnp | grep 8080
  

🔍 チェックポイント: 0.0.0.0:8080 または *:8080 であればDockerからアクセス可能

127.0.0.1:8080 の場合はサービス設定を変更する:

    # 例: Pythonの場合
python -m http.server 8080 --bind 0.0.0.0
  

NG行動(やってはいけないこと)

  • 本番環境で --network host を安易に使用 - セキュリティリスクが増大する
  • 0.0.0.0 バインドをセキュリティ考慮なしで設定 - 外部からもアクセス可能になる
  • ファイアウォールを無効化して解決 - 根本原因を隠蔽し、セキュリティを低下させる
  • IPアドレスをハードコード - 環境によってIPが変わるため動かなくなる

よくある質問(FAQ)

Q1: host.docker.internal はどの環境で使える?

A: Docker Desktop(macOS/Windows)では標準で使用可能。Linux(Docker Engine 20.10以降)では --add-host=host.docker.internal:host-gateway オプションが必要。

Q2: Docker Composeで別サービスに接続するには?

A: 同一 docker-compose.yml 内のサービスは自動的に同一ネットワークに参加する。サービス名で接続可能(例: http://db:5432)。

Q3: WSL2環境で特別な設定は必要?

A: Docker Desktop for Windowsを使用している場合、host.docker.internal はそのまま使用可能。WSL2内のDockerでは Linux と同様の設定が必要。

関連するエラー・症状

解決しない場合

公式ドキュメント

確認すべきログ

    # Dockerデーモンログ
journalctl -u docker.service

# コンテナログ
docker logs <container-id>
  

次に調べるキーワード

  • docker network inspect
  • docker bridge network
  • iptables docker