開發者工具 · · 約 16 分鐘閱讀

Docker 容器走主機 Clash:HTTP 代理環境變數與閘道兩種設定實測(2026)

許多人在本機或 CI 跑 Docker 時,容器內的 git clonenpm installpip 需要連外,卻不想在映像裡再裝一份 Clash,也不希望每個專案各自維護訂閱。最自然的想法是:讓容器沿用宿主機已在跑的 Clash。實務上常見兩條路:一是透過 HTTP_PROXY/HTTPS_PROXY(以及部分工具會讀的 ALL_PROXY)把支援代理的應用程式流量導到主機的 mixed-port;二是在 Linux 上把容器的預設閘道指到能轉發到 Clash 的路徑,讓整個網路命名空間的預設出站都經過主機。本篇以實測取向說明兩者差異、何時選哪一種、以及 host.docker.internalNO_PROXYallow-lan 等容易踩雷的細節;與站內 Ubuntu 上安裝 Clash Meta開發者網域分流等主題互補——這裡專注在容器如何接到主機上的那個 Clash 埠,不重複講完整訂閱匯入流程。

1. 為什麼幾乎都會想到「共用主機 Clash」

容器是隔離的執行環境:預設有自己的網路命名空間與 DNS 設定,不會自動繼承你桌面版 Clash 的 TUN 介面或系統代理。若你在主機上已經用 Clash 處理好訂閱、規則與策略組,在容器裡再跑第二套客戶端,等於重複維護兩份設定,映像體積與開機時間也變差。開發者真正想要的是:容器內的程式「像平常一樣」能連到 GitHub、npm registry、PyPI,而出口政策仍由主機那台 Clash 統一決定。

搜尋「docker 代理」或「容器走 clash」時,答案幾乎都落在兩類:應用層代理環境變數,或調整容器路由/閘道。兩者不是誰絕對比較好,而是相容性與維護方式不同:前者對大多數 CLI/套件管理器最友善;後者適合你希望不依賴每個工具是否支援 HTTP 代理、或要在實驗環境統一觀察所有封包走向的情境。

2. 主機端前置:監聽位址、mixed-port 與 allow-lan

無論選哪一種容器方案,主機上的 Clash 都必須在容器看得到的那張網卡上開放埠。預設只綁 127.0.0.1 時,從 bridge 網路進來的容器無法連回主機的代理埠,這是最常見的「主機瀏覽器正常、容器內全失敗」原因。實務上需要在設定中允許區域網路/非本機介面存取(常見選項名稱如 allow-lan),並確認 mixed-port(或你分開設定的 HTTP/SOCKS 埠)確實在監聽。實際 YAML 鍵名依你使用的 Clash 核心與圖形介面版本可能略有差異,請以目前使用的範本為準。

若你的主機是 Linux 伺服器或桌面,可搭配站內 Ubuntu 安裝 Clash Meta 與 systemd一文,把服務化與開機啟動先穩定下來,再回來調整埠與監聽範圍。完成後,建議在主機本機先用 curl 對 mixed-port 做一次探測,確認協定與回應符合預期,再進容器測試。

把代理埠開在 0.0.0.0 等同於對區域網路上其他裝置也暴露服務。請搭配防火牆、僅信任的家用網段、或公司 IT 政策;公共 Wi‑Fi 環境下更要避免大範圍監聽。

3. 作法一:HTTP_PROXY/HTTPS_PROXY 環境變數(實測主軸)

環境變數法的精神很單純:讓容器裡的行程在發起 HTTP/HTTPS 請求時,先把流量交給主機上的 Clash,再由 Clash 依規則決定直連或轉發到節點。多數開發者工具鏈(Git、npm、pip、部分版本的 curl/wget)會讀 HTTP_PROXYHTTPS_PROXY;有些還會看 ALL_PROXY 或大小寫並存的 http_proxy 變體,視執行環境而定。

Docker Desktop(macOS/Windows)通常提供 host.docker.internal 這個特殊主機名,讓容器解析到宿主機。代理 URL 可寫成 http://host.docker.internal:7890(埠號請替換成你實際的 mixed-port)。在Linux 原生 Docker,預設不一定內建此名稱,可改用在 bridge 上指向宿主機的閘道 IP(常見為 172.17.0.1,實際請以 docker network inspect 為準),或在 Compose 裡用 extra_hosts 自行對應到主機路由可達的位址。

單次執行範例(埠號請替換)

# HTTP and HTTPS via host mixed-port (Docker Desktop style)
docker run --rm -e HTTP_PROXY=http://host.docker.internal:7890 \
  -e HTTPS_PROXY=http://host.docker.internal:7890 \
  -e NO_PROXY=localhost,127.0.0.1,::1 \
  alpine sh -c 'wget -qO- https://example.com -O /dev/null && echo ok'

NO_PROXY(或 no_proxy)務必保留內部 registry、公司 Git、Kubernetes API、localhost 服務等不該繞一圈代理的主機名與 IP,否則會出現「內網反而連不上」的反常現象。清單越長越需要版本控管,建議與團隊約定一份共用的環境變數片段,在 Compose 或 CI 秘密變數裡引用即可。

若你同時在調整 Clash 規則與策略組,讓特定開發者網域走穩定節點,可一併參考 Cursor 與開發者網域分流一文;本篇假設規則已在主機 Clash 就緒,只差容器如何把 TCP 連到那個埠

4. 作法二:Linux 閘道與容器預設路由(全域出站)

當某些工具不讀 HTTP_PROXY,或你希望在測試環境統一觀察所有出站 IP,可以改從網路層下手:讓容器的預設閘道指向主機上會把流量轉進 Clash 的路徑。實作上可能涉及主機 IP 轉發iptables/nftables、或自建 bridge 與靜態路由,細節高度依散佈環境而變,沒有單一「複製貼上就能用」的指令適用所有機房。

這條路的優點是對應用程式透明:不必猜每個二進位是否支援代理。缺點是除錯成本高,且一旦路由或 NAT 配錯,症狀會是「整台容器斷網」而不是單一指令失敗。實測時建議先在一台可拋棄的 VM上驗證,並用 tcpdump、Clash 日誌對照封包是否真的進入核心;若你只是要讓 npm/git 連外,多數團隊仍會優先採環境變數

另一個常見變體是 --network host,讓容器共用主機網路命名空間;在 Linux 上這會讓容器直接沿用主機路由與本機埠,有時能「順便」吃到主機 TUN 或 iptables 規則,但可攜性與隔離性變差,也不利於 Compose 多服務埠衝突管理,除非你很清楚為何需要,否則不建議當成預設解。

5. 兩種做法對照:相容性、除錯與維護成本

實測經驗來看,HTTP 代理環境變數在開發者日常(拉映像、裝依賴、跑單元測試前要連外下載)最省事:設定集中在 Compose 或 CI YAML,問題發生時只要把代理關掉或改 NO_PROXY 就能對照。缺點是非 HTTP 生態自行實作連線的程式可能完全忽略這些變數,此時就會出現「同一容器裡有的指令成功、有的失敗」的割裂感。

閘道/路由較接近「機房網工思維」:一次調好,所有 IP 封包都跟著走。缺點是落地與除錯門檻高,且容易與公司 VPN、公司代理、或主機上其他防火牆規則互相打架。若你正在調整自動選節點與備援,可搭配 url-test/fallback 策略組,讓主機 Clash 在容器大量連線時仍維持穩定出口,但路由法本身不會自動解決「應用程式不支援代理」的問題——兩層要分開想。

6. Compose、BuildKit 與 CI 流水線怎麼帶入

Docker Compose 裡,可把代理變數寫在服務的 environment 區塊,或使用 env_file 統一載入,避免每個開發者手動 export。建置映像階段若需要連外抓套件,請留意 BuildKit 與傳統 docker build 傳遞 build-arg/環境的差異:有時執行 RUN npm ci 的是建置器內的另一層環境,變數沒傳進去會建置失敗,這時要在 Dockerfile 用 ARGENV 明確銜接。

Compose 片段示意(鍵名請依專案調整)

services:
  app:
    build: .
    environment:
      HTTP_PROXY: http://host.docker.internal:7890
      HTTPS_PROXY: http://host.docker.internal:7890
      NO_PROXY: localhost,127.0.0.1,.internal.company

CI(GitHub Actions、GitLab CI 等)若跑在遠端無 Docker Desktop 的 Linux runner,通常要自己決定「CI 機器上的代理埠」或「sidecar 容器」策略;此時 host.docker.internal 可能不存在,需改填 runner 可路由到的主機 IP 或內部代理服務名稱。實務上很多團隊會在 CI 使用明確的內部 HTTP 代理主機名,而不是假設與開發者筆電同構,這點在寫文件時建議寫清楚,避免新人複製本機 Compose 到 CI 後全失敗。

7. 安全與區網暴露:不要為了省事開太大洞

只要 Clash 的 mixed-port 對區網開放,等同於在內網提供一個可轉發流量的服務:任何能連到該埠的裝置,理論上都能借用你的節點與規則。家用環境或許可接受,但公司筆電、共享實驗室應評估是否改為僅本機socat/SSH 轉發,或把代理放在專用 VLAN。容器內也請避免把代理變數寫進會公開的映像層(含機密或內網位址時改用 build secret 或 runtime env)。

此外,請區分「技術上能連」與「政策上允許」:某些企業網路禁止自行搭出口,違規可能觸及資安稽核。本文僅說明技術實測與設定層級的取捨,實際部署請遵循你所在環境的規範。

8. 驗證清單與常見錯誤訊息

建議依序確認: 主機上 Clash mixed-port 對 bridge 可連(必要時暫時用第二台容器 pingnc 測埠); 容器內環境變數是否真實存在(envprintenv); NO_PROXY 是否誤傷內網位址; Clash 日誌是否出現對應連線,若完全沒有,代表流量仍繞過代理或沒到主機埠。

常見錯誤包含:Connection refused(主機沒聽或防火牆擋)、Could not resolve host: host.docker.internal(Linux 未手動加入別名)、以及 HTTPS 憑證錯誤(若你中間還掛了 MITM 或公司 SSL 檢查,需另裝 CA)。每遇到一類錯誤,先判斷是DNS路由還是應用程式不支援代理,再決定要不要從環境變數改走閘道路線,或反過來。

訂閱與規則仍不確定時

若主機 Clash 尚未完成訂閱匯入或規則覆寫,可先到 訂閱匯入教學把基底補齊;容器端代理只是把「出口」接到已存在的那台 Clash,無法替代訂閱與策略組本身。

寫在最後

DockerClash 都是「組合拳」型工具:映像與網路命名空間決定連線從哪裡出發,主機上的 Clash 決定出去之後怎麼分流。把兩者接起來,最務實的路往往是先把 HTTP_PROXY/HTTPS_PROXYNO_PROXY 寫對,再視需求評估是否要動到閘道與路由。這樣你在本機寫程式、跑整合測試、或在 CI 拉依賴時,都比在容器內重裝一份客戶端來得好維護

相較於介面停滯、日誌資訊稀少的舊方案,持續演進的 Clash 生態在觀測連線調整規則上通常更直覺;當容器與主機共用同一套策略,也比較不會出現「筆電能上、CI 全掛」的謎之落差——前提是環境變數與監聽位址真的對齊。

若你希望用同一個安裝包完成訂閱、系統代理或 TUN、以及後續規則微調,建議從本站 下載頁取得適合主機系統的用戶端,先把 mixed-port 與 allow-lan 確認無誤,再回頭套用到 Docker 工作流程。當主機端穩了,容器只要指對那一個埠,開發節奏會順很多。若你準備好把代理變數與 Clash 日誌對照一次,現在即可開始:→ 立即免費下載 Clash,開啟流暢上網新體驗

依主題相關度匹配的延伸閱讀,涵蓋同分類下的實戰配置文章。