wheel/sdist 時,併發、逾時、鏡像與鎖檔一致性比「換一個工具」更關鍵。本文以對照表與可複製指令整理 uv 環境變數、失敗排查與 CI 校驗步驟。站內延伸:依賴拉取 FAQ、Rust lockfile 矩陣;英文延伸(免登入):Git/Docker 拉取加速、快取策略與 CI。
① 場景界定:pip、uv、conda 何時優先選 uv?
遠端 Mac CI 常見痛點是「大量小檔+高延遲」:解析 metadata、下載 wheel、偶發 sdist 編譯全擠在同一個 job。uv在單機上擅長並行解析與快取重用;若你已有 pyproject.toml 且希望與 Python CI 鎖檔工作流一致,通常比純 pip 腳本更易維護。conda/mamba仍在科學運算二進位堆疊(非 PyPI 生態)有優勢;純 PyPI 專案不必硬拆成 conda。
| 工具 | 適合場景 | 跨境批量拉取 | 鎖檔/可複現 |
|---|---|---|---|
pip | 既有腳本、簡單 venv | 需手調 timeout/retries/index | requirements.txt 無鎖時易漂移 |
| uv | 現代專案、CI 要快、要鎖 | 內建並行下載+統一快取目錄 | uv.lock 或 uv pip compile 產出帶雜湊清單 |
| conda/mamba | 頻繁用 conda-forge 二進位 | 頻寬與 channel 策略獨立於 PyPI | environment.yml+顯式版本 |
決策規則(2026 實務):以 PyPI/私有索引為主、要在遠端節點批量裝套件 → 優先 uv;必須混用大量 conda 套件 → 保留 conda,PyPI 側仍可用 uv 子環境處理。
② 可執行參數矩陣:併發、逾時、重試、快取、鏡像
下列環境變數在遠端 Mac 的 shell、LaunchAgent 或 CI env: 區塊皆可使用。鏡像 URL 請替換為你合規且同步正常的PyPI 鏡像(範例域名僅示意)。
| 變數/行為 | 建議值(弱網/跨境) | 用途 |
|---|---|---|
UV_CONCURRENT_DOWNLOADS | 4~16 起測 | 限制同時下載 wheel/sdist;過高易 429/連線重置 |
UV_CONCURRENT_BUILDS | 1~4 | 並行編譯 sdist;遠端 Mac 記憶體有限時宜保守 |
UV_HTTP_TIMEOUT/HTTP_TIMEOUT | 120~300(秒) | 讀取逾時;弱網先拉高再調併發 |
UV_HTTP_CONNECT_TIMEOUT | 15~45 | TCP/TLS 握手階段逾時 |
UV_HTTP_RETRIES | 5~10 | 暫態 5xx/斷線重試 |
UV_CACHE_DIR | 如 $HOME/Library/Caches/uv-ci | 固定快取路徑便於掛卷與清理 |
UV_DEFAULT_INDEX | https://pypi.org/simple 或鏡像 | 主 Simple API(新版優先);舊名 UV_INDEX_URL 仍常見 |
UV_INDEX/額外索引 | 空白分隔之多個 Simple URL | 次要鏡像或私有倉(避免同名套件衝突) |
| CI 層重試 | GitHub Actions retry 等 | uv 重試仍失敗時整步重跑 |
# 遠端 Mac 或 CI job 內(bash/zsh)
export UV_CACHE_DIR="${UV_CACHE_DIR:-$HOME/Library/Caches/uv-ci}"
export UV_DEFAULT_INDEX="${UV_DEFAULT_INDEX:-https://pypi.org/simple}"
# 跨境改走團隊核可鏡像時(請替換為實際 URL):
# export UV_DEFAULT_INDEX="https://your-mirror.example.com/simple"
export UV_CONCURRENT_DOWNLOADS="${UV_CONCURRENT_DOWNLOADS:-8}"
export UV_CONCURRENT_BUILDS="${UV_CONCURRENT_BUILDS:-2}"
export UV_HTTP_TIMEOUT="${UV_HTTP_TIMEOUT:-180}"
export UV_HTTP_CONNECT_TIMEOUT="${UV_HTTP_CONNECT_TIMEOUT:-30}"
export UV_HTTP_RETRIES="${UV_HTTP_RETRIES:-8}"
uv sync --frozen --no-dev
# 僅 requirements 流:可先 compile 再安裝
# uv pip compile pyproject.toml -o requirements.lock
# uv pip install -r requirements.lock
鏡像切換:同一 pipeline 內統一 UV_DEFAULT_INDEX/UV_INDEX,勿混用未約定的多組公開鏡像;切換後用下一節乾淨校驗跑一輪。
③ 跨境網路下的失敗模式與排障(TLS/憑證/代理)
TLS 握手失敗/憑證不受信任:企業 SSL 攔截時,將內部根憑證匯出為 PEM,設定 SSL_CERT_FILE 與 REQUESTS_CA_BUNDLE 指向同一路徑;可視 uv 版本嘗試 UV_NATIVE_TLS=true 或 UV_SYSTEM_CERTS=true 讓 macOS 鑰匙圈參與校驗。
代理不一致:同時設定 HTTPS_PROXY/HTTP_PROXY,並用 NO_PROXY 排除內網私有索引主機名,避免「metadata 走代理、wheel 直連」半套配置。
症狀對照:頻繁 Read timed out → 先升 UV_HTTP_TIMEOUT/UV_HTTP_RETRIES,再酌降 UV_CONCURRENT_DOWNLOADS;403/429 → 降併發或換時段;連線被重置 → 檢查 middlebox 與 MTU。
export HTTPS_PROXY="http://127.0.0.1:7890" export HTTP_PROXY="http://127.0.0.1:7890" export NO_PROXY="localhost,127.0.0.1,.corp.internal,private.pypi.example.com" export SSL_CERT_FILE="/path/to/company-root-ca.pem" export REQUESTS_CA_BUNDLE="$SSL_CERT_FILE" uv sync --frozen -v
與 Git/Docker 大流量並行時,可參考站內繁中:Git 與 Docker 拉取加速,將頻寬與代理策略在 Runbook 層面對齊。
④ 與 requirements.lock/pyproject 的一致性校驗與 CI 可複現步驟
單一真相來源:要嘛以 uv.lock 為準(uv sync --frozen),要嘛以 uv pip compile 產生的 requirements.lock(含雜湊)為準;勿在 CI 同時「解鎖升級」又要求 byte-for-byte 可複現。
PR 閘道:維護者在與 CI 相同 OS/Python 版本執行 uv lock 或 uv pip compile,提交鎖檔 diff;review 時檢查是否意外放寬版本範圍。
乾淨校驗:定期在空 UV_CACHE_DIR 或新 runner 上跑 uv sync --frozen,確認鎖檔與索引狀態仍一致。
# CI:嚴格依鎖安裝(失敗即紅燈,避免 silent upgrade) uv sync --frozen --no-dev # 產生/更新鎖(僅在開發機或維護 job) uv lock # 可選:檢查 lock 是否與 pyproject 不同步 uv lock --check
| 鎖檔型態 | CI 指令 | 注意 |
|---|---|---|
uv.lock | uv sync --frozen | 與 pyproject 綁定;平台標記要與遠端 Mac 對齊 |
requirements.lock(pip 相容) | uv pip install -r requirements.lock | 建議由 compile 產生含雜湊版本 |
無鎖只有 requirements.in | 禁止直接上線依賴解析 | 跨境下「當下最新」會造成漂移 |
⑤ FAQ:快取污染、平台 wheel、私有索引混用
會。共用 runner 時為每個 job 設定獨立 UV_CACHE_DIR,或在關鍵 release job 使用乾淨目錄;搭配 --frozen 與鎖檔雜湊,可把漂移壓到最小。
manylinux wheel 與 macOS arm64 標籤不同。應在目標平台(或 uv 支援的平台矩陣選項)上產生/驗證 lock,避免 CI 在 Mac 上才發現缺輪子。
以 UV_DEFAULT_INDEX(或相容的 UV_INDEX_URL)設主鏡像,再以 UV_INDEX 追加私有倉 Simple URL;兩邊都需可走通代理與憑證鏈。套件名稱若可能在兩邊同名,應在倉庫政策上禁止覆寫。
總結:2026 年在遠端 Mac做 Python CI,用 uv 統一解析與快取,再以 UV_CONCURRENT_DOWNLOADS、UV_HTTP_TIMEOUT、UV_HTTP_RETRIES、UV_DEFAULT_INDEX 扛跨境批量拉取;鎖檔與 --frozen 才是可複現核心。若流水線還含 Git/Docker 大流量,可搭配英文站Git/Docker 拉取加速與快取策略一併規劃。需要穩定 Apple Silicon 節點與頻寬環境,歡迎從MacPull 首頁查看套餐,並至定價、購買頁選擇合適方案;操作說明見說明中心(皆無需登入即可瀏覽)。