對開發者來說,VPN 的價值不只是開啟網頁,而是讓每天反覆使用的 Git、Docker、npm、pip、Homebrew,以及 CI/CD 工具,在不同網路環境下都能維持可預期的連線。GitHub clone 速度慢、Docker Hub 映像檔拉取中斷、npm install 在解析套件時逾時,表面上看起來像是工具本身故障,實際上往往與 DNS、代理模式、TLS 連線、分流規則或單一出口路徑有關。
本文以實際開發流程為主軸,整理桌面 VPN 用戶端、訂閱匯入、Git 代理、Docker daemon、npm 設定與 CI/CD 執行器之間的關係。重點不是把所有流量一律導向同一條線路,而是先判斷哪一層沒有使用代理,再用最小範圍的設定完成修正。這樣既方便排查,也能避免本機服務、公司內網或套件鏡像被不必要地繞路。
先理解開發工具的網路路徑
一般瀏覽器通常會遵循作業系統的 HTTP 或 HTTPS 代理設定,因此啟用系統代理後,瀏覽器可能立即恢復正常。但 Git、Docker 和 npm 的行為並不完全相同。Git 有自己的 global 設定;Docker CLI 會將請求交給 Docker daemon;npm 則會讀取 npmrc、環境變數與 registry 設定。當這些程式分別執行在不同程序、容器或遠端機器上時,代理是否生效更不能只看桌面右下角的連線狀態。
90+
國家覆蓋
200+
線路數
不限
同時在線設備
5
支援平台
選擇線路時,也要分清楚「代理協定」與「上游網路路徑」。Shadowsocks、VMess、Trojan、VLESS、Hysteria2、TUIC 和 WireGuard 屬於不同的連線協定或 VPN 技術,負責處理客戶端與遠端入口之間的連線方式;IEPL、BGP、CN2 等則是線路或網路路由描述,不能將它們當成同一類設定。實際體驗仍會受本地網路、DNS、遠端服務負載和目標站點限制影響。
| 工具或服務 | 常見請求 | 優先檢查位置 | 常見誤區 |
|---|---|---|---|
| Git | HTTPS clone、fetch、push,或 SSH 連線 | Git global 設定、環境變數、SSH 設定 | 只開啟系統代理,卻沒有讓 Git 讀取代理 |
| Docker | 從 registry 取得映像檔與 layer | Docker daemon 的代理、registry mirror、DNS | 只替 Docker CLI 設定代理,daemon 仍未設定 |
| npm | registry metadata、tarball、套件相依性 | npm config、registry 位址、npmrc | 把 registry 問題誤判成 VPN 節點問題 |
| CI/CD | 拉取原始碼、安裝依賴、建置映像檔 | Runner 所在主機與工作容器的環境變數 | 本機可以使用,不代表遠端 Runner 也能使用 |
用戶端與訂閱設定:先求穩定,再做分流
Windows、macOS、Linux、Android 和 iOS 都可以使用官方用戶端;若需要更細緻的規則管理,也可以選擇 Clash Verge、sing-box 或 Shadowrocket 等相容客戶端。這些用戶端的介面不同,但基本流程相同:取得訂閱連結、匯入遠端設定、更新節點、選擇合適協定,然後啟用系統代理或 TUN 模式。
訂閱連結本身通常包含帳戶對應的存取憑證,應該像密碼一樣處理。不要將完整連結貼到 issue、公開 gist、團隊聊天紀錄或錯誤截圖中。若需要請他人協助排查,應遮蓋網域後的識別參數,並刪除可能包含帳戶資訊的日誌內容。
- 從使用者面板複製完整訂閱連結,確認複製內容沒有多餘空格或換行。
- 在用戶端的「訂閱」「Profiles」「遠端設定」或相近入口新增連結。
- 執行更新,確認節點名稱、協定項目與更新時間確實出現變化。
- 先選擇一條穩定線路測試,再逐步加入規則分流,不要一開始就大幅修改設定。
- 確認系統代理或 TUN 模式已啟用,並檢查本機代理連接埠是否與工具設定一致。
規則分流對開發者特別有用。可以讓 GitHub、Docker registry、npm registry 等指定網域經由代理,而讓本機 localhost、區域網路服務、公司內部網域或已知的本地鏡像維持直連。若使用 TUN 模式,流量涵蓋範圍通常比單純系統代理更廣,但也可能與 Docker Desktop、虛擬機、企業安全軟體或其他 VPN 發生衝突。排查時應一次只變更一項設定。
- ✅ 先確認訂閱已解析,再處理 Git、Docker 和 npm 的個別設定。
- ✅ 優先使用官方用戶端或與訂閱協定相容的 Clash Verge、sing-box、Shadowrocket。
- ✅ 開發工具出現問題時,保留用戶端日誌與工具自身的錯誤訊息。
- ❌ 不要同時啟用兩個會修改系統代理、TUN 或虛擬網卡的用戶端。
- ❌ 不要在公開文件中留下完整訂閱連結、代理密碼或帶有憑證的環境變數。
GitHub 與 Git:分辨 HTTPS、SSH 和代理層
GitHub 相關操作通常分為 HTTPS 和 SSH 兩種。HTTPS 會連線到遠端網域並傳輸 repository、tag 或 release 資料,Git 可透過 global 設定使用 HTTP 或 SOCKS 代理。SSH 則由 SSH client 建立連線,通常需要在 SSH 設定檔中另外指定 ProxyCommand 或跳板方式。只在 Git 的 HTTPS 設定中加入代理,不會自動改變 SSH 的行為。
如果使用 HTTPS remote,可以先查看現有設定,再決定是否加入代理。以下指令只示範檢查與設定方向,代理位址和連接埠必須替換成實際用戶端顯示的本機值:
git remote -v
git config --global --get http.proxy
git config --global --get https.proxy
git config --global http.proxy http://127.0.0.1:本機連接埠
git config --global https.proxy http://127.0.0.1:本機連接埠
如果用戶端提供的是 SOCKS5 代理,Git 的寫法要依版本與環境支援情況調整,例如使用 socks5h:// 讓網域解析也交由代理處理。這一點很重要:socks5:// 和 socks5h:// 的 DNS 行為不同,前者可能仍在本地解析目標網域,後者則通常將解析請求交給代理端。若遇到能連線但解析失敗的情況,應查閱目前 Git 版本支援的格式,而不是盲目重複執行設定。
完成設定後,先用低成本操作測試,例如查看 remote、執行 fetch 或取得一個小型 repository。若出現 TLS 憑證錯誤,不要直接關閉 SSL 驗證。這可能表示系統時間不正確、代理核心改寫了連線、企業網路插入憑證,或 Git 使用了錯誤的代理位址。關閉驗證會降低連線安全性,應先從憑證鏈、系統時間和代理模式開始排查。
SSH 的問題則要看 SSH 自身的輸出。可使用詳細模式確認它卡在 DNS、TCP 建立、金鑰交換還是驗證階段:
ssh -vT [email protected]
若團隊環境要求 SSH 經由代理,應在使用者 SSH 設定檔中建立清楚、可撤銷的規則,而不是修改整個系統的網路行為。ProxyCommand 所需的工具和語法會因 Windows、macOS、Linux 以及所使用的核心而不同,設定前先確認本機代理是否支援 SOCKS 或 HTTP CONNECT。測試完成後,記得檢查 Git remote 是否仍指向預期的官方網域,避免把問題誤歸因於節點。
Docker 映像檔拉取:設定 daemon,而不只是 CLI
Docker pull 失敗是開發環境中最容易誤判的問題之一。使用 docker pull 時,命令列只是向 Docker daemon 發出請求,真正連線到 registry、解析網域和下載 layer 的,可能是 Docker Desktop 背後的 daemon 或 Linux 上的 systemd 服務。因此,即使瀏覽器和 Git 已經可以使用 VPN,Docker 仍然可能因為 daemon 沒有代理而逾時。
第一步是確認錯誤類型。若錯誤涉及 DNS lookup,先檢查 Docker 執行環境中的 DNS;若出現 connection refused,通常是代理位址或連接埠不正確;若下載中途斷線,則要同時考慮代理協定、MTU、UDP 限制、registry 回應以及單一 layer 的傳輸狀況。不要只看到「timeout」就不停切換節點,先留下完整錯誤訊息。
Linux 上可透過 systemd drop-in 為 Docker daemon 指定 HTTP、HTTPS 和排除清單。以下是概念範例,實際路徑與代理格式應依發行版、Docker 安裝方式和用戶端提供的本機代理而定:
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:本機連接埠"
Environment="HTTPS_PROXY=http://127.0.0.1:本機連接埠"
Environment="NO_PROXY=localhost,127.0.0.1,.local"
# 修改後重新載入服務設定,再重啟 Docker daemon
Docker Desktop 則要在其設定介面中檢查代理選項,因為 Desktop、Linux VM、容器內部和宿主機並不一定使用同一份設定。設定完成後,重新啟動 Docker Desktop 或 daemon,再執行簡單的 registry 請求。若拉取仍然失敗,可分別測試 registry 的 DNS、HTTPS handshake 和映像檔 manifest,並確認是否有公司網路的 TLS 檢查或防火牆政策。
Registry mirror 也值得留意。鏡像可以減少遠端 registry 的重複請求,但鏡像本身必須可信、可用,且不一定涵蓋所有私有映像檔或最新標籤。不要為了追求速度,把不明鏡像直接加入全域 Docker 設定。若團隊有固定的私有 registry,應按照管理員提供的憑證、CA 和網域設定 NO_PROXY,避免內部服務被導向外部代理。
- ✅ 先判斷請求是由 Docker Desktop、Linux daemon 還是遠端 Runner 發出。
- ✅ 只為必要的 registry 設定代理,內部 registry 和本機網域加入適當的 NO_PROXY。
- ✅ 修改 daemon 設定後重新啟動相關服務,再重新測試 pull。
- ❌ 不要把宿主機的 127.0.0.1 直接當成容器或遠端 Runner 的代理位址。
- ❌ 不要因為某個公共鏡像速度較快,就忽略來源可信度與憑證驗證。
npm 與其他套件管理器:先確認 registry,再調整代理
npm install 同時涉及 registry metadata、套件 tarball 和相依套件解析。當其中一個請求受到 DNS、TLS 或代理影響,就可能呈現為整體安裝逾時。先查看目前 npm 的有效設定,不要猜測設定檔位置:
npm config get registry
npm config get proxy
npm config get https-proxy
npm config list
如果確認需要使用本機 HTTP 代理,可以在 npm 設定中指定;若用戶端只提供 SOCKS5,應先確認 npm 版本與相關代理支援方式,必要時使用能將 SOCKS 轉為 HTTP CONNECT 的本機入口。不要把一個 SOCKS 位址直接當成 HTTP 代理填入,這會導致連線立即失敗或錯誤訊息不明確。
npm config set proxy http://127.0.0.1:本機連接埠
npm config set https-proxy http://127.0.0.1:本機連接埠
npm config get cafile
若 registry 位址本身可以正常連線,但特定套件下載失敗,應檢查套件是否由另一個 tarball 網域提供。npm 的 metadata 來源和實際壓縮檔下載位置可能不同,只有確認兩者都能解析和建立 HTTPS 連線,才能判斷是 registry、代理或套件來源的問題。
npmrc 中也可能殘留舊代理、過期 token 或公司內部 registry 設定。團隊專案常見的做法是把公開 registry、私有 scope 和認證設定分開管理,避免把個人 token 提交到版本庫。對於 CI/CD,應透過受保護的 secret 或環境變數注入憑證,並限制 token 權限與有效範圍。
pnpm、Yarn、pip、Go modules 和 Homebrew 也有各自的 registry 或 proxy 設定。不要以為修改 npm 就會影響所有工具。更有效率的排查順序是:先確認系統能解析目標網域,再確認工具實際使用的 registry,最後查看工具自己的 verbose log。當系統代理和工具專用代理同時存在時,還要確認是否發生雙重代理或環境變數覆蓋。
CI/CD 與完整排查流程
本機可以 clone、pull 和 install,不代表 CI/CD 一定能完成相同工作。Runner 可能位於另一個網路、容器或虛擬機中;它看不到你本機用戶端的 127.0.0.1,也不會自動繼承桌面系統代理。若工作流程需要透過代理存取 GitHub、容器 registry 或套件來源,應在 Runner 所在主機或工作容器中明確設定 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY,並依平台文件重新啟動服務。
容器建置時還要區分 build 階段和 runtime 階段。Docker build 下載基礎映像檔時由 daemon 處理;RUN npm install 或 RUN apt-get update 時,則可能由建置容器內的程序發出請求。只設定 daemon 代理,未必能讓 build container 內的套件管理器使用代理;反過來,只把代理環境變數傳入容器,也不會解決基礎映像檔拉取失敗。
建議採用由外到內的排查順序:
- 確認本地基礎網路可用,並檢查系統時間、DNS 和防火牆狀態。
- 確認 VPN 用戶端目前使用的模式、節點、協定和本機監聽連接埠。
- 用瀏覽器或命令列測試目標網域的 DNS 解析與 HTTPS 連線。
- 查看 Git、Docker daemon、npm 或 CI Runner 是否真的讀取代理設定。
- 逐一測試 Git fetch、Docker pull 和 npm install,不要一次執行整個大型建置流程。
- 恢復不必要的全域設定,將可用的代理範圍縮小到必要工具與目標網域。
日誌中的錯誤類型通常能提供方向。ENOTFOUND 或類似 DNS 錯誤,表示名稱解析需要先處理;ECONNREFUSED 多半與本機代理沒有啟動、連接埠錯誤或服務拒絕連線有關;TLS handshake 或 certificate 錯誤則應檢查系統時間、CA 憑證、企業網路檢查和代理核心設定。下載中途的 reset、unexpected EOF 或 checksum mismatch,可能與連線不穩、快取損壞或遠端服務回應有關,應先清理單一工具的快取並重試,而不是直接刪除所有系統設定。
完成測試後,記錄一份團隊可維護的設定說明:使用哪個用戶端、哪些網域走代理、哪些內部網域直連、Git 使用 HTTPS 還是 SSH、Docker daemon 設定放在哪裡,以及 CI secret 由哪個管理系統注入。不要只記錄「開 VPN 後就可以」,因為這種描述無法幫助下一位開發者定位問題,也容易讓本機有效的設定被錯誤搬到容器或 Runner。