為何 2026 遠端 Mac 要分開談「輸入鎖」與「substituter」
flake.lock 鎖 inputs(如 nixpkgs 修訂);substituter 是二進位 URL 清單,決定能否下載 nar。兩者解耦:同一 lock 在不同地域可能 miss 而觸發大量本機編譯,拖垮共享 runner。
- 輸入漂移:CI 內默默
nix flake update易讓綠燈與開發機不一致。 - substituter 順序:內網鏡像置前可降出境;缺
trusted-public-keys會整段失敗。 - 併發與磁碟:
max-jobs與下載連線過高時,/nix與系統卷同碟易 IO 佇列。
對照表:本機 store/遠端 substituter/自建快取
以 nar 下載依賴度對照法遵、命中率與維運成本。
| 來源 | 命中/延遲 | 法遵與信任 | 維運 | 較適合 |
|---|---|---|---|---|
本機二進位快取(同一 runner 的 /nix/store 命中) | 最快;冷啟動為零 | 資料不出機;路徑需與 lock 一致 | 低;需規劃 gc 與快取保留策略 | 固定映像、重複建置、高頻 MR |
遠端 substituter(cache.nixos.org、社群/上游 Cachix) | 跨境時延與抖動大;熱門路徑命中高 | 需 trusted-public-keys;出境流量需稽核 | 低–中 | 開源依賴為主、可接受公網快取 |
| 自建/區域二進位快取(企業 Hydra/Attic/內網 S3 前置) | 內網 RTT 低;首包仍須種子 | 金鑰與 ACL 自控;易滿足資料邊界 | 高(同步、簽章、監控) | 釋出產線、混合閉源依賴、嚴格邊界 |
可複製的 nix.conf 範本(substituters、金鑰、max-jobs、cores)
寫入 /etc/nix/nix.conf 或 NIX_USER_CONF_FILES;替換佔位符。順序:內網/自建 → cache.nixos.org → 可選社群。
# 2026 遠端 Mac CI 建議起點(請依法遵刪減 substituters) substituters = https://<YOUR_INTERNAL_CACHE> https://cache.nixos.org https://<YOUR_CACHIX>.cachix.org trusted-public-keys = <YOUR_INTERNAL_CACHE_KEY> cache.nixos.org-1:6NCHdD59Z431Q0QK348AG5BK86JQ28DRVGV15KVX- <YOUR_CACHIX>.cachix.org-1:<YOUR_PUBLIC_KEY> max-jobs = auto cores = 0 # 跨境網路:收斂連線與逾時(依 Nix 版本微調鍵名;不支援可刪) binary-caches-parallel-connections = 8 connect-timeout = 10 # 多使用者 CI:僅信任 root/daemon(示例) trusted-users = root
| 情境 | 建議 | 備註 |
|---|---|---|
| 共享遠端 Mac、單 job | max-jobs = 2 或 auto 搭配 CPU 上限 | 避免與其他租戶搶滿編譯執行緒 |
| 專用 M 系列、單一流水線 | max-jobs = auto、cores = 0 | cores = 0 常見語意為「讓 Nix 自行選每作業核心數」;仍以實測為準 |
| 大量 substituter miss | 下調 max-jobs 與平行連線 | 先救磁碟與頻寬,再調快取順序 |
Flake lockfile:更新與回滾命令
CI 預設應固定 lock,變更走 MR/PR;流水線內更新須留 diff/artifact 稽核。
更新單一輸入(例如只升 nixpkgs):nix flake lock --update-input nixpkgs
更新所有輸入:nix flake update;若需直接寫入提交可視流程加上 --commit-lock-file(慎用)。
回滾 lock:git restore --source=HEAD~1 flake.lock 或 git checkout <已知良好修訂> -- flake.lock,再重跑 nix build/nix develop -c …。
# 僅驗證 lock 與 flake 完整性(不改檔) nix flake check --no-write-lock-file # 在乾淨工作樹上鎖定當前 flake.nix 所宣告輸入(寫入 flake.lock) nix flake lock # 針對單一輸入重新解析並寫 lock nix flake lock --update-input nixpkgs
需 lockfile 掃描可參考:GitHub Checks lockfile 掃描。
失敗重試與磁碟水位閾值(參數清單)
常見失敗:TLS 中斷、5xx、nar 雜湊不符、逾時。以 shell 退避重試 包 nix build,並聯動磁碟監控。
| 維度 | 建議值/階梯 | 決策備註 |
|---|---|---|
| 下載/建置重試 | 3–5 次;秒數 4+jitter→8→16,封頂 120 | 對 TLS/暫態 5xx;若連續 nar 雜湊錯誤應停並檢查金鑰/鏡像污染 |
/nix 可用空間警戒 | 18–22% 剩餘比例 | 觸發 nix-collect-garbage 或限流;多租戶節點宜偏保守 |
/nix 嚴重 | 12–15% | 停止接受新任務或強制只讀快取路徑;附 df -h 快照到日誌 |
系統卷(非 /nix) | 警戒 18–20%、嚴重 12–15% | 日誌與 tmp 同卷時,編譯暫存會與 store 競爭 |
# 示例:包裝 nix build 的指數退避(占位:將 .#default 換成你的 flake 目標) set -euo pipefail for i in 1 2 3 4 5; do nix build ".#default" --print-build-logs --no-link && exit 0 s=$((4 << (i-1))) [ "$s" -gt 120 ] && s=120 sleep $((s + RANDOM % 5)) done exit 1
總結:對照表選邊界;nix.conf 固定 substituter、金鑰、max-jobs、cores;lock 更新可審計、可 git 回滾;退避重試與磁碟閾值守節點。頁首 JSON-LD 含 BlogPosting、BreadcrumbList、HowTo。