## 🐳 當你覺得合併 [[Docker]] 網路很麻煩,又想「緊急」透過主機埠通訊時 {#sec-f27028c85270} 通常情況下,容器之間通訊的標準做法是建立一個共用橋接網路,然後透過服務名稱(例如:`http://app-b:8080`)來呼叫。然而,有時我們會遇到一些「不可避免的情況」,讓標準方法難以實行。 ## 如果遇到這些「無奈的狀況」,不妨試試這個方法 {#sec-3da904d03848} * **需要與直接安裝在主機上的服務通訊時:** 當資料庫(DB)或 Redis 直接安裝在主機作業系統而非容器中,導致無法合併網路時。 * **因是他人建立的容器,擔心修改網路設定會出問題時:** 當你管理非本人建立的複雜網路設定,擔心將自己的容器強行加入會導致故障時。 * **在本地開發中,只想「暫時」確認連線時:** 當你不管網路設計,只想立即確認請求是否能送達透過主機埠開放的服務時。 在這些情況下,一個非常實用的「作弊碼」就是 `host.docker.internal`。 ![使用主機在容器之間通訊的示意圖](/media/whitedec/blog_img/4e661ed1ddb648529e5b1681c022cd25.webp) --- ## 解決方案:「窺探容器外世界的窗口」`host.docker.internal` {#sec-979a012d89c8} 在容器內部呼叫 `127.0.0.1` 只會指向容器本身。此時,使用 `host.docker.internal` 這個特殊網域名稱,就能穿透容器的壁壘,找到主機的 IP 位址。 **Python (DRF) 程式碼範例:** ```python # 使用 'host.docker.internal' 而非 'localhost' 來透過主機埠連線。 # 如果 App-B 綁定到主機的 8080 埠,則如下所示呼叫: NEXTCLOUD_URL = "http://host.docker.internal:8080" response = requests.get(NEXTCLOUD_URL) ``` --- ## ⚠️ [[Linux]] 用戶必須進行「手動設定」 {#sec-169e1a1f873c} 雖然 Docker Desktop (Mac/Windows) 預設支援此功能,但在**純粹的 Linux 伺服器**中,Docker 不會自動設定此網域名稱。您必須在建置或執行時明確指定:「此網域名稱代表主機 IP」。 **Docker Compose 設定範例:** ```yaml services: drf-app: image: my-drf-app-image extra_hosts: # 宣告以 host.docker.internal 的名稱存取主機閘道 - "host.docker.internal:host-gateway" ``` --- ## 這並非永遠是最佳解 {#sec-bb28e4a13c7f} 再次強調,這種方法更像是**最後的手段**。 1. **最佳方法:** 建立共用橋接網路並透過容器名稱通訊(安全性最高)。 2. **使用此方法的原因:** 當需要存取直接在主機上運行的程序,或處於無法合併網路結構的「孤立」環境時。 請將去年記錄的這種「應急通道」使用方法,視為在常規方法受阻時才動用的秘密武器!