title: “Dockerコンテナからlocalhostに接続できない” date: 2026-01-16 draft: true description: “Dockerコンテナ内からlocalhostやホストマシンのサービスに接続できない場合の確認手順と対処法を解説” categories: [“runbook”] tags: [“runbook”, “docker”, “localhost”, “ネットワーク”, “接続エラー”, “host.docker.internal”]
症状
Dockerコンテナ内から localhost や 127.0.0.1 に接続しようとすると、接続が拒否される・タイムアウトする
結論:まずこれを確認
- コンテナ内の
localhostはコンテナ自身を指す(ホストマシンではない) - ホストマシンに接続するには
host.docker.internalを使用する - 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 refused か Connection 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 inspectdocker bridge networkiptables docker