DockerコンテナからホストPCへアクセスする方法
1. はじめに
コンテナ化されたアプリケーションがホストマシン上で動作するサービスにアクセスする場面は少なくありません。例えば、ローカルで立ち上げたデータベース、モックサーバー、デバッグ用の HTTP サーバーなどです。本稿では、ホスト ↔ コンテナ間通信の仕組みを理解した上で、macOS / Linux / Windows それぞれの最適解を解説します。
2. 基礎知識 – Dockerネットワークの仕組み
Docker はデフォルトで bridge ネットワークを作成し、各コンテナを仮想ブリッジに接続します。ホスト側には
- Linux:
docker0インターフェース(例:172.17.0.1/16) - macOS / Windows: 軽量 VM 内に同等の仮想ブリッジ
が生成されます。
| OS | ホスト側ブリッジ | ホストアクセス用ホスト名 | 備考 |
|---|---|---|---|
| macOS | HyperKit VM 内 | host.docker.internal |
DNS で解決 |
| Windows | WSL2 VM 内 | host.docker.internal |
DNS で解決 |
| Linux | docker0 |
なし(IP 直打ち) |
172.17.0.1 など |
3. macOS 編 – host.docker.internal の活用
Docker Desktop (macOS) では、ホストのゲートウェイアドレスを FQDN host.docker.internal として自動公開しています。
3.1 サンプル: HTTP サーバーへのアクセス
# ホスト側 (macOS) – ポート8000で HTTP サーバーを起動
python3 -m http.server 8000
Dockerfile
FROM python:3.12-slim
RUN apt-get update && apt-get install -y curl
CMD ["curl", "http://host.docker.internal:8000"]
# ビルド & 実行
$ docker build -t mac-host-access .
$ docker run --rm mac-host-access
3.2 Docker Compose での記述例
services:
app:
image: python:3.12-slim
command: ["curl", "http://host.docker.internal:8000"]
Compose ファイルからでも同名で解決されるため追加設定は不要です。
3.3 制限とトラブルシューティング
- VPN/Proxy: corporate VPN で DNS が上書きされると名前解決に失敗する場合あり。
- ファイアウォール: macOS の PF またはアプリ固有 FW がポートをブロックしていないか確認。
-
複数ネットワーク:
host.docker.internalはデフォルトルートを指す。複数 NIC の場合はブリッジ経路を確認。
4. Linux 編 – 172.17.0.1 とカスタムブリッジネットワーク
Linux ではホスト OS に直接 Docker Engine が動作しており、ブリッジインターフェース docker0 が生成されます。
4.1 docker0 インターフェースを確認する
$ ip addr show docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 ...
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
4.2 サンプル: コンテナ → ホスト HTTP サーバー
# ホスト側
python3 -m http.server 8000
# コンテナ側(対話的に)
$ docker run --rm -it curlimages/curl http://172.17.0.1:8000
4.3 --add-host で名前解決を統一する
複数 OS で同一イメージを使いたい場合、Linux でも host.docker.internal を使えると便利です。
docker run --add-host=host.docker.internal:host-gateway \
curlimages/curl http://host.docker.internal:8000
Docker 20.10 以降は
host-gatewayキーワードで自動的にゲートウェイ IP が解決されます。
Docker Compose (v3)
services:
app:
image: curlimages/curl
extra_hosts:
- "host.docker.internal:host-gateway"
command: ["http://host.docker.internal:8000"]
5. Windows 編 – Docker Desktop / WSL2 環境
WSL2 をバックエンドに採用している Docker Desktop for Windows でも host.docker.internal が利用可能です。ただしネットワーク構造が複雑になるため注意点があります。
5.1 host.docker.internal 利用パターン
# PowerShell でホスト側に HTTP サーバーを起動
PS> python -m http.server 8000
# コンテナからアクセス
> docker run --rm curlimages/curl http://host.docker.internal:8000
5.2 WSL2 内部ネットワークの挙動
- Docker Desktop が自動生成する NAT ネットワーク
172.28.0.0/20などが存在。 - WSL2 ディストリビューションからは
localhost→ Windows ホストへ転送されるが、Docker VM からは異なる。
5.3 よくある落とし穴
| 症状 | 原因 | 解決策 |
|---|---|---|
host.docker.internal が解決できない |
WSL2 の DNS キャッシュ不整合 |
wsl --shutdown で再起動 |
| ポートが到達しない | Windows Defender Firewall | 該当ポートを許可 |
| Proxy 環境で403/timeout | システム環境変数 HTTP(S)_PROXY | コンテナ側に無効化設定を反映 |
6. 共通のベストプラクティス
-
Listen Address を
0.0.0.0に – Flask や Node.js はデフォルトで127.0.0.1バインド。ホストからの接続を受け付けない。 -
ポート競合監視 –
lsof -i :PORTで既存プロセスを確認。 -
Compose で環境変数置換 – OS ごとに異なる値を
.envで切り替え。 - VPN / ZeroTrust – 名前解決が阻害されるケースが多い。split‑tunnel 設定を推奨。
-
セキュリティ – 開発用途でも外部へ露出しないよう
ufw/pfctlでローカル限定アクセスに。