Docker Hub 拉取逾時,未必是映像檔或節點故障
在終端機執行 docker pull 時,Docker 不只是連到一個網站下載檔案。一次拉取通常會先向 Docker Hub 取得映像檔資訊,再向授權服務索取權杖,接著連到 Registry 取得映像檔各層;不同階段可能使用不同主機名稱與 CDN。只要其中一段連線無法建立、TLS 握手停住,或下載 CDN 被規則送往不合適的出口,畫面就可能長時間停在 Pulling fs layer、反覆重試,最後顯示 context deadline exceeded、i/o timeout 或連線重設。
排查時最容易犯的錯,是只在終端機設定 HTTP_PROXY 和 HTTPS_PROXY,然後直接假設 Docker Engine 也會使用相同代理。實際上,Docker CLI、Docker daemon、Docker Desktop 背後的虛擬機,以及 Clash 核心各自可能有不同的網路環境。你在瀏覽器成功開啟 Docker Hub,也不代表負責下載映像檔的 daemon 已經走上同一條代理路徑。
因此應先把現象拆成幾個問題:Clash 節點本身能否連線?目前使用的代理模式是否涵蓋 Docker 流量?Docker daemon 是否真的取得代理設定?解析到的 DNS 位址是否可用?最後再用連線紀錄與 docker pull 的實際結果交叉確認。每次只改一個條件,才能知道修正是否有效,而不是在換節點、換 DNS、改規則之間碰巧成功,卻留下難以重現的設定。
先定位失敗階段:認證、Registry 還是映像層下載
先記下完整錯誤訊息、映像名稱、標籤與發生時間,不要只保留最後一行「拉取失敗」。例如 unauthorized 或 pull access denied 通常應先檢查映像名稱、私有倉庫權限與登入狀態;no such host 指向名稱解析或 DNS;connection refused 常與代理監聽位址、連接埠或防火牆有關;而 i/o timeout、TLS handshake timeout 才更像路徑不通、封包遭丟棄或出口品質不穩。錯誤文字不是絕對診斷,但可以幫你決定先查哪一層。
可先用 docker pull hello-world 或另一個小型公開映像做對照,再重試原本的大型映像。若小映像也在連線或認證階段失敗,優先檢查代理、DNS 與授權服務;若小映像成功,只有特定映像的某一層停住,則應觀察該次拉取是否切換到 CDN、是否有特定出口連線中斷,以及是否遇到本機磁碟空間不足。大型映像容易讓網路問題更明顯,但下載速度慢本身不等於 Clash 規則錯誤。
也可以從宿主機檢查 Registry 的 HTTPS 回應。對公開 Registry 的 /v2/ 路徑收到 401 Unauthorized,在沒有帶認證資訊時往往是正常的:它代表 HTTPS 連線已抵達 Registry,只是服務要求先取得授權。相反地,DNS 錯誤、連線逾時或憑證握手失敗,才值得繼續沿著代理和解析路徑追查。宿主機測試成功仍不能單獨證明 Docker daemon 可用,因為兩者可能走不同的網路設定。
檢查 Clash 模式、規則命中與節點狀態
在 Clash Verge、Clash Verge Rev、Mihomo Party 或其他 Mihomo 客戶端中,先確認核心已啟動、目前設定檔已載入,並選取一個實際可用的代理策略組。接著查看客戶端的連線紀錄:在執行 docker pull 的同一時間,是否出現相關連線?若完全沒有紀錄,流量可能沒有經過目前的 Clash 入口;若有紀錄,請留意命中的規則、連線類型與最後選到的節點,而不是只看策略組介面上顯示的延遲。
「規則」模式下,Docker Hub 相關連線可能被不同網域規則分別處理。授權主機、Registry 主機和實際傳送映像層的 CDN 不一定共用同一個網域後綴,因此只為常見的 Registry 主機加一條規則,未必涵蓋整個下載流程。可以在拉取期間查看 Clash 連線紀錄,記錄實際出現的主機名稱,再依需要為相關主機設計範圍適當的規則。不要因為網路文章列出一份網域清單,就不經確認地加入大量過寬規則;服務端點可能調整,過度涵蓋也可能意外改變其他流量的出口。
為了快速分辨是否為規則分流問題,可在自己有權使用的網路環境中,暫時將模式切換為「全域」並選擇已確認可用的節點,再執行一次相同的拉取測試。若全域模式可成功、規則模式失敗,線索較偏向規則命中或策略組選擇;若兩種模式都失敗,應接著查 Docker daemon 的代理、DNS、節點品質或網路限制。測試完成後記得切回日常模式,避免把全域代理當成永久修補方案。
若連線紀錄顯示連線已分配到節點,卻反覆逾時,可先換到另一個穩定節點,再觀察同一主機的結果。不要一次更改節點、DNS 模式、TUN 與路由規則,否則即使成功,也難以知道真正的故障點。若節點切換後只有 CDN 連線恢復,可能是特定出口至該 CDN 的路徑品質不同;這時應讓相關連線使用穩定、可持續的策略,而不是盲目追求測速數字最低的節點。
確認 Docker daemon 的代理設定,不只看終端機
在 Linux 上,Docker Engine 通常由 systemd 管理。你在互動式終端設定的 HTTPS_PROXY,不一定會傳遞給以服務方式啟動的 daemon;因此先查看 daemon 的服務狀態與啟動環境,再依目前 Docker Engine 的官方文件設定代理。採用 systemd drop-in 時,變更後需重新載入 systemd 設定並重啟 Docker 服務,之後再確認 daemon 已重新啟動且沒有設定解析錯誤。請先備份原有設定,並避免把含帳號密碼的代理 URL 留在公開日誌或畫面截圖中。
Docker Desktop 的情況不同:daemon 通常位於 Desktop 管理的虛擬環境中,主機上的 127.0.0.1 不一定能直接代表 Desktop 內的代理服務。優先使用 Docker Desktop 目前版本提供的代理設定介面,依其說明指定 HTTP/HTTPS 代理或系統代理,再套用變更並重新測試。不同作業系統與 Desktop 版本的選項名稱可能不同,請以實際介面和版本文件為準,不要直接照搬 Linux systemd 的設定方式。
Clash 的 HTTP 或 mixed port 常見於本機回環位址,但代理服務必須能從發出連線的那一端抵達。如果 daemon 與 Clash 不在同一個網路命名空間,代理 URL 寫成 127.0.0.1:7890 可能指向 daemon 自己,而非執行 Clash 的主機。遇到這種架構時,先釐清 Docker Engine、Desktop 虛擬機與 Clash 分別位於哪個環境,再依平台支援的方式選擇可達的代理位址;不要為了方便就把代理埠公開到不可信的區域網路。
設定代理後,重新啟動 daemon 或 Desktop,再查看 Docker 的資訊輸出與相關服務日誌,確認代理值是否被載入。若終端機的 curl 可經代理連線,但 docker pull 仍逾時,這通常是重要線索:問題可能不在 shell,而在 daemon 取得的設定、Desktop 虛擬環境的可達性,或 daemon 流量沒有按預期進入 Clash。除錯時可記錄代理主機、連接埠和是否存在 NO_PROXY,但公開分享時請遮蔽憑證與內部位址。
排查 DNS、TUN 與容器網路的差異
DNS 問題通常會以 no such host、解析結果不穩,或同一個網域在不同測試環境得到不同位址的方式出現。先分別在宿主機和 Docker daemon 所在環境確認解析結果,再對照 Clash 的 DNS 設定與連線紀錄。若使用 fake-ip,請確認目前客戶端的 DNS 模式、規則與核心設定彼此一致;若曾切換 DNS 模式或匯入新設定檔,重新啟動核心並清理舊快取後再測試,避免把過期解析結果誤認為新設定仍然失效。
不建議一開始就把 DNS 改成任意公共解析器。這可能讓單一測試看似恢復,卻使 Clash 的網域規則判斷、分流或本地網域解析出現新的差異。較好的做法是先確認故障在哪個解析環節:宿主機能否解析?Docker daemon 使用的解析路徑是否相同?Clash 日誌中是否出現相關 DNS 請求或解析錯誤?定位後再調整 DNS 上游或快取,且每次修改後都用同一個映像名稱重測。
啟用 TUN 時,Docker daemon 的流量可能由虛擬網卡和路由規則接管;在 Linux 上,Docker bridge、轉送規則、防火牆或 Strict Route 等設定也可能影響容器與宿主機的連線。先用最小變更確認宿主機流量是否進入 Clash,再檢查 daemon 的出站紀錄與路由。若問題只在開啟 TUN 後出現,應比較啟用和停用 TUN 時的路由、日誌與測試結果,而不是立刻重設 Docker 網路或清空所有防火牆規則。
另外要區分「拉取映像檔」與「容器執行後連不上網」。docker pull 是 daemon 向外取得映像層;容器啟動後的應用程式流量則走 Docker 網路與容器的 DNS 設定。兩者可能使用不同的路徑。若映像已成功拉取,但容器內的應用程式無法連線,排查方向應轉為容器 DNS、網路模式、主機代理可達性和應用程式自身的代理支援,而不是繼續修改 Registry 規則。
用可重複的測試確認修復,而不是只看一次成功
修正後先重試原本失敗的映像與標籤,並保留測試時間、使用模式、選取的節點和結果。若原映像已經部分下載,Docker 可能重用本機已有的映像層,因此一次成功不必然代表每個下載階段都已經穩定。可再選一個未曾下載、大小適中的公開映像做交叉測試,確認認證、Registry 查詢與映像層傳輸都能正常完成。不要在沒有必要時反覆刪除所有映像快取;這會增加流量,也可能令問題更難復現。
建議把每次測試整理成簡單紀錄:Clash 使用規則或全域模式、當時節點、Docker daemon 是否已設定代理、DNS 是否有調整、錯誤發生階段,以及 Clash 連線紀錄是否出現相關主機。若只有某一節點失敗而其他節點成功,先處理出口路徑品質;若全域成功、規則模式失敗,核對實際命中的規則;若宿主機 HTTPS 測試成功而 daemon 失敗,回頭檢查 daemon 或 Desktop 的代理設定;若主要錯誤是解析失敗,則聚焦 DNS。這種逐層對照比「換一份設定檔試試」更省時間。
當拉取能穩定完成後,再恢復原本需要的規則模式或 TUN 設定,重複一次相同測試,確認日常配置也有效。若設定檔由訂閱或覆寫規則管理,請把必要變更放在不會被更新覆蓋的位置,並記錄修改目的;下一次更新或重啟後再驗證一次。若網路屬於公司、學校或雲端主機環境,也要確認代理使用方式符合管理政策,並留意防火牆、TLS 檢查或出站連線限制可能影響 Docker Hub。
常見問題
瀏覽器能開 Docker Hub,為什麼 docker pull 還是逾時?
瀏覽器可能使用 Clash 的系統代理,但 Docker daemon 未必使用相同設定。先確認 daemon 或 Docker Desktop 的代理選項,再對照拉取時的 Clash 連線紀錄;瀏覽器可用只能證明瀏覽器那條路徑可用,不能代表 Docker daemon 已經走代理。
看到 unauthorized 就一定是 Clash 代理問題嗎?
不一定。公開映像在未認證時,部分 Registry 路徑回傳要求授權的回應可能是正常流程;若最終錯誤是權限不足,請檢查映像名稱、標籤、帳號登入狀態與私有倉庫權限。若錯誤同時包含網路逾時或無法連到授權服務,再回頭檢查代理與 DNS。
只設定 HTTP_PROXY/HTTPS_PROXY 就足夠了嗎?
不一定。這些環境變數是否生效,取決於使用它們的程式與服務啟動環境;Docker Engine 可能由 systemd 啟動,Docker Desktop 則可能在虛擬環境中執行。請依平台確認 daemon 實際載入的代理設定,不要只以目前終端機的環境變數作為判斷。
映像拉取成功,但容器內連不上網,要改 Docker Hub 規則嗎?
通常不必。拉取映像檔是 daemon 的出站流量,容器執行後則使用 Docker 網路與容器自己的解析、代理設定。請改查容器 DNS、網路模式與代理位址是否可達,並以容器內的實際錯誤定位問題。
與手動維護大量網域清單或只靠終端環境變數的做法相比,穩定的 Clash 工作流程應能讓你看見規則命中、核對節點出口,並清楚分辨宿主機、Docker daemon 與容器網路的差異;部分只提供簡化開關的代理工具,往往不容易追查 Docker Desktop 或 TUN 下的流量究竟走到哪裡。若你希望在同一介面管理 Mihomo 核心、代理策略與連線紀錄,可前往下載 Clash V.CORE,依本文的測試順序確認 Docker Hub 拉取路徑,再把驗證過的設定留在日常使用配置中。
// 編輯推薦
Clash V.CORE:更容易追查 Docker Hub 代理問題
從代理模式、策略選擇到連線紀錄,逐步確認 Docker 拉取映像檔時實際使用的網路路徑。
- 查看連線紀錄與規則命中結果
- 切換代理策略,對照不同節點出口
- 管理 Mihomo 核心與設定檔
- 搭配 TUN 模式檢查流量接管狀態