[Docker] 在無網絡共享的情況下,使用主機端口進行容器間通信 (host.docker.internal)
標籤: Docker, DevOps, Networking, host.docker.internal
1. 問題情況
在開發環境中經常使用 Docker 管理多個服務。
-
App-A(例如: DRF) 在network-A上。 -
App-B(例如: Nextcloud) 在network-B上。 -
這兩個容器在同一主機上運行。
-
App-B綁定到主機的8080埠。(例如:docker run -p 8080:80 ...)
App-A 需要通過 API 調用 App-B。我不想麻煩地將這兩個網絡通過橋接連接起來,那我能否直接調用主機的 8080 埠呢?
如果在容器內部調用 localhost:8080 或 127.0.0.1:8080,這指的不是主機,而是 容器本身。
2. 解決方案: host.docker.internal
最簡單的解決方案是使用名為 host.docker.internal 的特殊 DNS 名稱。
host.docker.internal: 在容器內部被解析為主機的 IP 地址的特殊主機名稱。
在 App-A (DRF) 的代碼中調用 Nextcloud 時,設置 URL 如下所示。
# DRF (App-A) 內部代碼
import requests
# 使用 'host.docker.internal' 代替 'localhost'
NEXTCLOUD_URL = "http://host.docker.internal:8080"
try:
response = requests.get(NEXTCLOUD_URL)
print(f"Nextcloud 連接成功: {response.status_code}")
except requests.exceptions.ConnectionError:
print("Nextcloud 連接失敗")
在容器內部使用 curl 測試時也是類似的。
# 在 App-A 容器內部執行
curl http://host.docker.internal:8080
3. ⚠️ 注意: Linux 主機環境設置
使用 Docker Desktop (macOS, Windows) 的用戶,host.docker.internal 預設可以正常運作。
但是在 Linux 主機 環境中,需要手動添加此設置。可以使用名為 host-gateway 的特殊關鍵字來映射主機 IP。
方法 1: 使用 docker run
添加 --add-host 標誌。
docker run \
--add-host=host.docker.internal:host-gateway \
--network network-A \
my-drf-app-image
方法 2: 使用 docker-compose.yml
為 App-A (DRF) 服務添加 extra_hosts。
services:
drf-app:
image: my-drf-app-image
networks:
- network-A
extra_hosts:
# 將 host.docker.internal 映射為主機 IP (host-gateway)
- "host.docker.internal:host-gateway"
# ... (network-A 定義) ...
4. 總結
在隔離的 Docker 網絡之間進行通信時,無需複雜地連接網絡。
-
將目標容器 (Nextcloud) 綁定到主機端口 (
8080)。 -
在調用的容器 (DRF) 中請求
http://host.docker.internal:8080地址。 -
如果主機是 Linux,切記在調用的容器中添加
extra_hosts(host.docker.internal:host-gateway) 設置。
目前沒有評論。