🐳 當你覺得合併 Docker 網路很麻煩,又想「緊急」透過主機埠通訊時
通常情況下,容器之間通訊的標準做法是建立一個共用橋接網路,然後透過服務名稱(例如:http://app-b:8080)來呼叫。然而,有時我們會遇到一些「不可避免的情況」,讓標準方法難以實行。
如果遇到這些「無奈的狀況」,不妨試試這個方法
- 需要與直接安裝在主機上的服務通訊時: 當資料庫(DB)或 Redis 直接安裝在主機作業系統而非容器中,導致無法合併網路時。
- 因是他人建立的容器,擔心修改網路設定會出問題時: 當你管理非本人建立的複雜網路設定,擔心將自己的容器強行加入會導致故障時。
- 在本地開發中,只想「暫時」確認連線時: 當你不管網路設計,只想立即確認請求是否能送達透過主機埠開放的服務時。
在這些情況下,一個非常實用的「作弊碼」就是 host.docker.internal。

解決方案:「窺探容器外世界的窗口」host.docker.internal
在容器內部呼叫 127.0.0.1 只會指向容器本身。此時,使用 host.docker.internal 這個特殊網域名稱,就能穿透容器的壁壘,找到主機的 IP 位址。
Python (DRF) 程式碼範例:
# 使用 'host.docker.internal' 而非 'localhost' 來透過主機埠連線。
# 如果 App-B 綁定到主機的 8080 埠,則如下所示呼叫:
NEXTCLOUD_URL = "http://host.docker.internal:8080"
response = requests.get(NEXTCLOUD_URL)
⚠️ Linux 用戶必須進行「手動設定」
雖然 Docker Desktop (Mac/Windows) 預設支援此功能,但在純粹的 Linux 伺服器中,Docker 不會自動設定此網域名稱。您必須在建置或執行時明確指定:「此網域名稱代表主機 IP」。
Docker Compose 設定範例:
services:
drf-app:
image: my-drf-app-image
extra_hosts:
# 宣告以 host.docker.internal 的名稱存取主機閘道
- "host.docker.internal:host-gateway"
這並非永遠是最佳解
再次強調,這種方法更像是最後的手段。
- 最佳方法: 建立共用橋接網路並透過容器名稱通訊(安全性最高)。
- 使用此方法的原因: 當需要存取直接在主機上運行的程序,或處於無法合併網路結構的「孤立」環境時。
請將去年記錄的這種「應急通道」使用方法,視為在常規方法受阻時才動用的秘密武器!