為什麼 Docker Hub 拉取映像檔會逾時

使用 Docker 拉取映像檔時,最容易誤判的情況是:瀏覽器可以開啟一般網站,Clash 連線紀錄也看似正常,但執行 docker pull 卻停在 Pulling from libraryWaitingRetrying,最後回報 context deadline exceededi/o timeout 或 TLS handshake 失敗。這不一定代表目前節點速度太慢,因為 Docker Engine 的連線路徑與瀏覽器不同,它可能由背景服務、虛擬機、WSL2 或 Docker Desktop 的獨立網路環境發出請求。

一次完整的 Docker Hub 拉取,通常不只連到一個主機。首先要取得 Registry API 的授權資訊,接著連線到 Docker Registry,再從內容分發網路下載映像檔的各個 layer。常見目的地包括 registry-1.docker.ioauth.docker.iohub.docker.com,以及實際分發 layer 的 CDN 網域。只把其中一個網域加入規則,並不代表整條下載流程都已經進入代理。

另外,Docker CLI 顯示的錯誤位置不一定是根因。例如 Registry API 已成功回應,真正失敗的是後續的 layer CDN;又或者 DNS 查詢先解析到一個目前出口無法連線的位址,導致你看到長時間等待。排錯時不要只重試同一個指令,也不要一開始就反覆更換節點,而是先確認請求有沒有進入 Clash、命中了哪條規則、DNS 回傳了什麼,以及 Docker Engine 是否真的使用同一個代理入口

先分辨 Docker、Clash 與 TUN 的流量邊界

Clash 的系統代理、TUN 模式與 Docker Engine 不是同一層功能。系統代理通常只會影響遵循作業系統代理設定的應用程式;Docker CLI 把請求交給 Docker daemon,而 daemon 可能在 Linux service、Docker Desktop 的 VM 或 WSL2 發出真正的外部連線。因此,即使瀏覽器已經可以透過 Clash 開啟 Docker Hub,Docker daemon 仍可能直接連線,甚至使用另一套 DNS。

使用方式 請求實際來源 常見問題 建議觀察位置
Linux 原生 Docker 宿主機上的 dockerd shell 的代理環境變數沒有傳給 daemon systemd 服務設定、Docker daemon 日誌
Docker Desktop Desktop 背景服務或內部 VM 主機代理與 Desktop 代理設定不一致 Desktop 設定、Clash 連線列表
WSL2 執行 Docker CLI WSL 網路與 Docker daemon 的組合 Windows 的 localhost 代理位址在 WSL 內不可直接使用 WSL 路由、nameserver、daemon 端設定
TUN 模式 由虛擬網卡接管符合條件的封包 路由衝突、DNS 劫持或 Docker 私有網段被誤接管 Clash 日誌、TUN 設定與系統路由表

這也是為什麼「我已經在 Clash Verge Rev 開啟系統代理」不能直接等同於「Docker 已經走代理」。若 Docker Engine 完全沒有出現在 Clash 的連線列表,優先處理流量入口;若列表中看得到請求卻顯示 DIRECT,才進一步檢查規則順序與網域匹配。

在啟用 TUN 之前,建議先記錄目前狀態,包括 Docker Desktop 是否正在執行、Docker daemon 的位置、Clash 的 mixed-port、TUN 的 DNS 模式,以及是否同時啟用了公司 VPN 或其他透明代理。排錯期間一次只改一個變數,否則即使問題消失,也很難知道真正有效的是代理、DNS,還是某個路由變更。

小提示:請先在 Clash 的連線頁面清除或縮小過濾範圍,再執行一次 docker pull hello-world。如果完全沒有新連線,別急著修改 Docker Hub 規則,先處理 Docker daemon 沒有進入 Clash 的問題。

設定 TUN 與 Docker Registry 分流規則

當 Docker daemon 不支援或不穩定地讀取 HTTP/HTTPS Proxy 時,TUN 可以作為較完整的驗證方式。對 Clash Meta 或 Mihomo 核心而言,TUN 會建立虛擬網卡,讓原本不會讀取代理環境變數的程式也有機會被導入規則引擎。不過,TUN 不是「開啟後所有問題自動消失」的按鈕;如果 DNS 模式、路由排除或規則順序錯誤,反而可能讓 Docker 網路、容器內服務與本機代理互相干擾。

在圖形介面中,先確認 TUN 的實作方式、堆疊模式與 DNS 設定。不同版本的 Clash Verge Rev 可能把選項放在「設定」「核心設定」或「TUN」頁面,名稱也可能略有不同。原則上,排錯時應先使用較容易觀察的設定,避免同時啟用多套 DNS 劫持、覆寫路由與特殊防火牆選項。若電腦上有公司 VPN,請先確認兩者是否會爭用預設路由;必要時暫停其中一套作 A/B 測試。

分流規則應涵蓋 Docker Hub 的控制面與資料面。可以在自訂規則或規則覆寫區加入下列方向,實際策略群組名稱請依你的設定檔調整:

rules:
  - DOMAIN-SUFFIX,docker.io,Proxy
  - DOMAIN-SUFFIX,docker.com,Proxy
  - DOMAIN,registry-1.docker.io,Proxy
  - DOMAIN,auth.docker.io,Proxy
  - DOMAIN-SUFFIX,dockerusercontent.com,Proxy
  - MATCH,DIRECT

上述片段的重點不是盲目把所有相關網域永久送往同一節點,而是先建立可驗證的基準。規則載入後,重新執行拉取,接著在連線列表搜尋 dockerregistryauth 或實際出現的 CDN 主機。若規則命中的是一個新的 CDN 網域,應根據連線紀錄補充必要的後綴,而不是猜測一大批網域。完成測試後,再依地區、服務需求與安全政策縮小規則範圍。

規則順序尤其重要。若上方已有 GEOIP,CN,DIRECT、某個大型規則集,或以 IP 分類為主的條款,Docker Registry 的網域規則可能永遠沒有機會被執行。將具體的 DOMAINDOMAIN-SUFFIX 放在寬泛規則之前,並在 Clash 的命中資訊中確認實際策略,才算完成設定。不要只看 YAML 已經寫入檔案,因為訂閱更新、設定合併與覆寫層級都可能讓你編輯的內容沒有真正生效。

實際排錯流程:從 DNS 到 layer 下載

第一步:確認 Docker daemon 的連線狀態

先執行簡單、體積很小的映像檔測試,避免大型 layer 讓問題被下載時間掩蓋。使用 docker info 確認 Docker 引擎可用,再執行 docker pull hello-world 或其他可信的小型公開映像。若 Docker CLI 本身就無法連線 daemon,這是 Docker socket 或服務狀態問題,與 Clash 分流尚無關係。

Linux 使用者可查看 daemon 的即時日誌,觀察錯誤是 DNS、代理連線、TLS,還是遠端回應碼。Docker Desktop 使用者則應同時查看 Desktop 的診斷資訊,因為終端機中的錯誤訊息只反映 CLI 與 daemon 之間的結果,不一定包含內部 VM 的完整原因。若能在 Clash 中看見 Registry 請求,請把發生時間、目的地與策略名稱記下來,後續每次修改都用同一組資料比對。

第二步:分開測試 DNS、TLS 與代理

DNS 能解析不代表 HTTPS 一定能連通;HTTPS 能建立連線,也不代表後續 layer CDN 會使用同一出口。先用系統工具查詢 registry-1.docker.ioauth.docker.io,再檢查返回的位址是否頻繁變動或落在目前網路無法到達的路徑。若開啟 TUN 後 DNS 結果與未開啟時完全不同,請記錄兩組結果,不要在尚未理解差異前反覆切換 fake-ip、redir-host 或系統 DNS。

接著用最小化的 HTTPS 請求測試 Registry API。只要能得到明確的 HTTP 回應,就表示 DNS、TCP 與 TLS 至少走完了一部分;如果命令停在連線階段,才應把重點放在出口節點、TUN 路由或防火牆。若 curl 使用了代理而 Docker 沒有使用,兩者結果不同是預期現象,不能拿來證明 Docker Hub 服務本身異常。

curl -I --connect-timeout 10 https://registry-1.docker.io/v2/
docker pull hello-world

在 Linux 上也可以檢查 daemon 是否取得代理設定。以 systemd 管理的 Docker 為例,代理通常需要放在服務的環境設定,而不是只寫在目前 shell:

sudo systemctl show --property=Environment docker
sudo journalctl -u docker --since "10 minutes ago"

如果你使用 Docker Desktop,請在 Desktop 自身的網路或代理設定中確認,而不是只在終端機執行 export HTTPS_PROXY=...。Windows、macOS 與 WSL2 的 localhost 位址也不能一概而論:宿主機上的 127.0.0.1 對 WSL 或容器網路未必代表同一台代理服務。這類情況比較適合使用可被對應環境存取的閘道位址,並以 Clash 連線列表驗證請求是否真的進入。

第三步:分辨 Registry、授權與 layer CDN

docker pull 可以開始列出 layer,但某一層長時間停住,通常表示控制面已經成功,問題集中在 layer 下載。這時不要只檢查 registry-1.docker.io,要回到 Clash 連線紀錄找出最後出現的目的地。不同映像、不同時間甚至不同 layer,可能會使用不同的內容分發主機;規則需要以實際紀錄為準。

若每次失敗的 layer 都不相同,可能是節點對長連線、HTTP/2、多路傳輸或大型回應不穩定。你可以在相同規則下更換策略群組中的節點,並用同一個映像重試;若只在特定節點失敗,根因較接近出口品質,而非規則。相反地,若所有節點都看不到 Docker 相關請求,則應回到 daemon、TUN 路由與代理入口檢查。

最常見的配置錯誤與修正方向

  • 只設定瀏覽器代理:瀏覽器通了不代表 dockerd 通了。請把測試對象改成真正發出請求的 Docker daemon,並在 Clash 連線頁面確認來源。
  • 只加入一個 Registry 網域:授權、Registry 與 CDN 可能是不同目的地。以實際連線紀錄補齊必要規則,避免只靠固定清單猜測。
  • 規則被寬泛條款提前攔截:檢查 GEOIP、大範圍 RULE-SETFINALMATCH 的排列順序,確保 Docker 專用規則在前。
  • 把 TUN 與其他 VPN 疊加:兩個虛擬網路介面可能同時修改路由或 DNS。排錯時先簡化成一個接管來源,再逐一恢復其他工具。
  • 錯把憑證問題當成節點速度:如果錯誤包含 certificate、handshake 或 x509,請先確認系統時間、根憑證、TLS 檢查工具與代理中介行為,不要只更換節點。
  • 容器內測試與宿主機測試混用:容器可能有自己的 DNS、預設路由與代理環境。應分別測試宿主機、Docker daemon 與容器內的連線結果。
  • 修改了錯的設定檔:訂閱主檔、覆寫檔與目前載入設定可能是三個不同檔案。每次修改後都要在介面確認核心已重新載入,並重新檢查規則命中。

完成修正後,建議用固定流程驗證:先重載 Clash 設定,再確認 TUN 或系統代理狀態;接著清除不必要的舊容器重試紀錄,執行小型映像拉取;最後測試一個包含多個 layer 的常用映像。每一步都記下時間與連線策略,這樣下次遇到逾時時,可以快速判斷是 DNS 變化、節點品質、CDN 路徑,還是設定更新造成的回歸問題。

常見問題

Docker Hub 逾時一定要開 TUN 嗎?

不一定。如果 Docker daemon 能正確使用 HTTP/HTTPS Proxy,透過規則分流通常更容易維護,也較不會影響區網服務。TUN 適合用來驗證不讀取代理環境的背景服務,或處理你無法在 daemon 端方便設定代理的場景。開啟前請先確認與 VPN、DNS 及 Docker 私有網段的相容性。

只加入 docker.io 就足夠了嗎?

通常不夠。Docker Hub 的授權、Registry 與 layer 分發可能使用不同主機。建議先加入必要的控制面規則,再從 Clash 連線列表觀察實際 CDN 網域;規則應以你的映像、網路環境與目前版本的連線結果為準,避免無限制擴大網域清單。

為什麼 curl 成功,docker pull 卻失敗?

最常見原因是兩者不是由同一個程序或網路環境發出請求。curl 可能讀取了目前 shell 的代理變數,而 Docker pull 由未設定代理的 daemon 執行;Docker Desktop 與 WSL2 也可能使用獨立的 VM 或網路介面。請在 Clash 連線紀錄確認 Docker 實際請求,再檢查 daemon 或 Desktop 的代理設定。

只有某些 layer 卡住,代表映像檔壞了嗎?

不一定。layer 下載可能分配到不同 CDN 路徑,某一個出口對長連線或大型回應不穩定,就會形成單層逾時。若映像摘要或 Registry 回應沒有顯示完整性錯誤,先比較不同節點、TUN 與規則命中結果;只有在多個正常出口都重現同一個摘要錯誤時,才需要進一步檢查本地儲存與映像來源。

相較於只提供單一全域開關、遇到 Docker 背景服務就難以確認流量去向的工具,Clash 能把 TUN、DNS、Registry 網域與策略群組拆開觀察:你可以先讓一般網站維持直連,再把 Docker 授權、Registry 與實際 CDN 精準導向代理,並透過連線紀錄追蹤每一層的命中結果。若你正在尋找一套能同時處理透明代理與細緻分流、又方便逐步排錯的方案,Clash 會讓 Docker Hub 逾時不再只能靠反覆換節點猜測。

立即免費下載 Clash,開啟流暢上網新體驗 →