問題形狀:為什麼 Clash 正常,Docker 卻像「沒開代理」

許多人在 macOS 或 Windows 上已用 Clash/Clash Verge Rev 把瀏覽器、IDE 更新與部分桌面程式都帶上節點,主觀感受是「網路已經通了」。但一回到終端機執行 docker pulldocker build,畫面卻卡在初始連線、層下載極慢,或直接報錯逾時。這種割裂很常見,原因並不一定是 Docker Hub 當天特別不穩,而是Docker Engine 拉映像、建置映像、以及容器執行這三條路徑,各自對「要不要讀 HTTP_PROXY」的規則並不相同;它們也不會自動去用你在 Clash 裡設定的「系統 Proxy」,除非你明確寫進引擎設定或把變數傳進建置/執行環境。

本文聚焦容器走宿主機代理裡最直白、也最可複製的一條路:讓需要連到公網 registry 的流量,改走主機上 Clash 對外開放的 HTTP 代理埠(常見為 mixed-port: 7890,實際請以你的設定為準)。這與本站 TUN 模式把整機流量納管 的策略不同:後者偏向「能進核心的封包都先經過虛擬介面」;本文則是「不改 TUN,只把 Docker 相關程序指到 http://主機位址:7890」,適合已在圖形用戶端跑穩 Clash、只想把容器與建置流程補齊的人。若你主要是在 WSL2 裡打指令而非 Docker Desktop 的 Linux VM,可併讀 WSL2 與 Windows 主機 Clash 一篇,兩者場景相鄰但網路命名空間不同。

三條路要分開設定:引擎拉映像、docker build、執行中的容器

實務上請把需求拆成三塊,避免「改了一處以為全部生效」。第一,Docker daemon 自己向 Docker Hub 或其他 registry 拉映像時,讀的是引擎組態(常見為 daemon.json 裡的 proxies),不是你在 shell 隨手 export 的變數。第二,docker build 預設會另外起建置環境;BuildKit 時代下,若要讓 RUN apt-getRUN curl 這類步驟走代理,通常要把 HTTP_PROXYHTTPS_PROXY 以 build-arg 或組態檔傳入。第三,已經 docker run 起來的長服務,若要在容器內抓公網套件,則要在該次執行或 Compose 的 environment 區塊帶入同一組變數。少做其中一環,就會出現「pull 已經快了,build 卻仍卡住」這種半套成功。

主機位址怎麼填:host.docker.internal 與 Linux 宿主閘道

在 Docker Desktop for Mac/Windows 上,容器內要連回「跑 Docker 的那台實體機」時,優先使用內建主機名 host.docker.internal。它會解析到可從容器路由到的主機位址,讓你把代理寫成 http://host.docker.internal:7890 而不用每次手動查 IP。若你在純 Linux 上跑 Docker Engine、沒有 Desktop 幫你維護這個名稱,可以於 docker run 加上 --add-host=host.docker.internal:host-gateway(或於 Compose 使用對應的 extra_hosts),讓自建環境也能沿用同一套字串,減少文件與腳本分叉。

無論哪一種平台,請先確認 Clash 在主機上確實監聽了你寫進 Docker 的那個埠,且已開啟「允許區網連線」(Allow LAN 或同等選項),否則容器即使能解析 host.docker.internal,連線仍會在 TCP 層被拒。Windows 使用者若曾遇連接埠衝突,可先對照 7890/mixed-port 排查 一文,再回來改 Docker 組態。

設定 Docker Engine 代理:daemon.jsonproxies

docker pulldocker push 這類由守護行程發起的連線走 Clash,請在 Docker Engine 組態中加入 proxies 區塊(路徑依安裝方式而異:Desktop 可在設定介面對應到 JSON,Linux 常見為 /etc/docker/daemon.json)。下列為示意,請將埠號改成你的 mixed-port 或獨立 HTTP 埠:

{
  "proxies": {
    "default": {
      "httpProxy": "http://host.docker.internal:7890",
      "httpsProxy": "http://host.docker.internal:7890",
      "noProxy": "localhost,127.0.0.1,::1"
    }
  }
}

修改後需要重啟 Docker 才會套用。若你公司內有私有 registry,請把其主機名或網段補進 noProxy,避免內部倉庫流量被誤送到公開節點。完成後可用 docker pull hello-world 這類小映像驗證;同時在 Clash 的連線紀錄裡應能看到來自 bridge 網段、目標為 registry 的 HTTP CONNECT 命中,這代表Docker Clash 代理路徑真的接通。

docker build 與 BuildKit:用 --build-argHTTP_PROXY

建置過程中的每一道 RUN 指令,其網路堆疊與你筆電 shell 預設無關。啟用 BuildKit 時,建議明確傳入:

docker build \
  --build-arg HTTP_PROXY=http://host.docker.internal:7890 \
  --build-arg HTTPS_PROXY=http://host.docker.internal:7890 \
  --build-arg NO_PROXY=localhost,127.0.0.1 \
  -t myimage:local .

若專案裡已有 Dockerfile,也可在開頭使用 ARG HTTP_PROXY 等宣告,讓 CI 與本機共用同一參數名稱。重點是:不要假設「daemon 已設代理,build 就一定跟著走」——在許多版本組合下,兩者是分開的。

docker compose 與執行中容器

對長駐服務,可在 Compose 的服務區塊加入:

environment:
  HTTP_PROXY: http://host.docker.internal:7890
  HTTPS_PROXY: http://host.docker.internal:7890
  NO_PROXY: localhost,127.0.0.1

若僅少數一次性容器需要代理,也可用 docker run -e HTTP_PROXY=...。請記得 NO_PROXY 要涵蓋你不希望經過 Clash 的內部 API 位址,否則除錯時會看到奇怪的連線延遲或憑證錯誤。

與 Docker Desktop「鏡像加速」並用會不會衝突?

在中國大陸等環境,許多人會在 Docker Desktop 或 daemon.json 設定registry mirrors,讓拉取改走國內快取節點。Clash 的 HTTP 代理與鏡像加速是不同層次:前者決定「這條 TCP 連線要不要經過你指定的 HTTP CONNECT 代理」,後者決定「解析哪一個 mirror 的位址來下載層資料」。兩者可以並存;若 mirror 本身已能極速直連,你也可以把該 mirror 的主機名加進 noProxy,讓流量不必再繞一圈本機 Clash,減少延遲。反之,若 mirror 仍需跨境,就讓它走代理。實務上以實測拉一層大映像的總耗時為準,而不是死記口訣。

建議排查順序(濃縮版)

  1. 確認 Clash 正常、mixed-port(或 HTTP 埠)數值正確,且已允許區網連線。
  2. 從任一容器內 curl -v --proxy http://host.docker.internal:7890 https://example.com 測試代理可達性(依你的測試網域替換)。
  3. 設定 daemon.jsonproxies,重啟引擎後再 docker pull
  4. docker build 補上 --build-arg HTTP_PROXYHTTPS_PROXY
  5. 為常駐服務在 Compose/run -e 帶入相同變數,並維護好 NO_PROXY
  6. 必要時再調整 registry mirror 與 noProxy 的取捨,並用 Clash 日誌核對規則命中。
ℹ️
與原生 Linux 上跑 Clash 的差異 若 Docker 與 Clash 都裝在同一台 Linux 實體機、且沒有 Desktop 幫你隔 VM,代理位址往往可直接用 127.0.0.1:7890;完整服務化部署可延伸閱讀 Ubuntu 上 Clash Meta 與 systemd。本文則鎖定「主機圖形用戶端已開 Clash、Docker 在另一層網路命名空間」這種最常見的桌面開發情境。
⚠️
合規與風險提醒 請在所在地法令允許的範圍內使用代理服務;本文僅說明本機開發環境的網路設定位置,不提供任何違法用途指引。請勿將允許區網連線的代理埠暴露給不受信任的網路,並妥善保管訂閱與設定檔。

結語:把 Docker 納入你已驗證過的 Clash 出口

相較於盲目更換節點或重裝 Docker,先把「引擎/建置/執行」三條代理路徑拆開檢查,通常能一次解決大半 Docker pull 逾時 的困擾。當 HTTP_PROXYHTTPS_PROXY 都穩定指向主機上的 Clash HTTP 埠,再配合合理的 NO_PROXY 與可選的 Docker Desktop 鏡像加速,本機容器開發體驗會明顯收斂到可預期的狀態。若你希望先取得整理好的多平台用戶端與更新說明,建議從本站下載頁選擇對應系統,並搭配 說明與教學文件 建立長期可維護的設定習慣;相較於四處搜尋來路不明的安裝包,這條路徑通常更安全、也更容易跟上核心版本。→ 立即免費下載 Clash,開啟流暢上網新體驗