雲端 Mac mini 多節點建置編排實戰

CI/CD 實踐 ·約 6 分鐘閱讀

雲端 Mac mini 多節點建置編排實戰

發布前夜,專案裡的主 App、今日小工具、Apple Watch 隨附應用三個 target 一起全量編譯,單機跑完要 38 分鐘。團隊沒有常年養一套自建 CI 叢集的預算,但發布日確實等不起。後來我們摸索出一個折衷方案:發布當天臨時租三台雲端 Mac mini,組成一支「一日建置農場」,用 SSH 矩陣把任務分派出去,編譯結束後統一簽章、匯聚產物,全程不到 15 分鐘就能拿到三個可上傳的封裝檔。這篇文章記錄這套編排的完整做法。

什麼時候值得搭多節點

不是所有專案都需要這麼折騰。判斷標準很直接:單次全量編譯超過 20 分鐘,或者一次發布要同時產出多個 target、多種架構的封裝檔,才值得臨時多開幾台節點。如果只是日常寫程式、跑單元測試,一台 Mini Standard(24GB 記憶體)完全夠用,常年開三台反而是浪費。

多節點農場的核心思路是「按天租用、隨用即撤」:發布窗口前一晚下單,發布完成後立即釋放,費用只發生在真正需要平行算力的那一天。

農場拓撲與節點分工

我們按各節點的網路路徑與資源條件挑選角色。分工前先在控制台確認各節點目前可選的機型檔位,把重編譯角色排到網路路徑和資源都合適的節點上。

節點角色 套餐 晶片/記憶體 位置 天價 負責內容
主編譯節點 Mini Pro M4 Pro / 64GB 美國西部 $59.3/天 主 App target,同時兼簽章匯聚
編譯節點 A Mini Standard M4 / 24GB 東京 $40.1/天 今日小工具 target
編譯節點 B Mini Standard M4 / 24GB 首爾 $40.1/天 Watch App target

三台合計 $139.5/天。作為對比,若全部換成 Mini Pro 則是 $177.9/天——小工具和 Watch App 的編譯負載本身不重,用 Standard 檔位就夠,把預算留給真正吃記憶體的主 App 編譯。

教訓:一開始我們把三台節點都放在東京,結果主編譯節點與簽章節點合併成一台後,rsync 內網互傳雖快,但美西節點承擔了後續 App Store Connect 上傳,反而離上傳目標更近——簽章節點選靠近上傳出口的地域,比選靠近開發者的地域更重要。

分派腳本與執行

協調機通常就是主編譯節點本身,用一支簡單的 Bash 腳本把 target 分派給各從屬節點,背景平行執行,最後統一等待:

#!/bin/bash
set -e

NODES=("node-a.internal" "node-b.internal")
TARGETS=("WidgetExtension" "WatchApp")

for i in "${!NODES[@]}"; do
  ssh "build@${NODES[$i]}" \
    "cd ~/repo && xcodebuild -scheme ${TARGETS[$i]} \
     -configuration Release -archivePath build/${TARGETS[$i]}.xcarchive \
     archive CODE_SIGNING_ALLOWED=NO" &
done

xcodebuild -scheme MainApp -configuration Release \
  -archivePath build/MainApp.xcarchive archive

wait
echo "all targets archived"

關鍵在於從屬節點帶上 CODE_SIGNING_ALLOWED=NO,只產出未簽章的 .xcarchive,證書完全不需要同步到那兩台機器上。主編譯節點自己帶證書,負責 MainApp 的簽章編譯,同時等待其他節點的產物。

產物匯聚與集中簽章

從屬節點編譯完成後,用 rsync 把 .xcarchive 推回主節點:

rsync -avz build@node-a.internal:~/repo/build/WidgetExtension.xcarchive ./build/
rsync -avz build@node-b.internal:~/repo/build/WatchApp.xcarchive ./build/

三個 archive 到齊後,在主節點用同一份描述檔與證書統一跑 xcodebuild -exportArchive,再用 fastlane 的 pilot upload 一次性傳三個封裝檔到 TestFlight。整個簽章環節只在一台機器上發生,私鑰不落地到從屬節點,這一點在檢查安全基線時會被反覆確認。

下單前建議過一遍自查清單:

常見問題與邊界

多節點編排也有不划算的場景。如果專案只有一個 target,或者全量編譯本身就在 10 分鐘以內,拆分成多節點反而會因為 SSH 排程、rsync 傳輸產生額外等待,不如老老實實用一台節點跑完。另外,首爾節點目前沒有 Pro/Max 檔位,如果三個 target 裡有一個記憶體占用特別高(比如帶機器學習模型推論的 target),要提前把它排到東京或美西的 Pro/Max 節點,而不是硬塞進首爾的 Standard 節點。

常見問題

多節點建置農場適合什麼規模的專案?

單次全量編譯超過 20 分鐘,或需要同時產出多個 target(主 App、Widget、Watch App)與多架構包時才值得搭建。日常單人開發用一台 Standard 節點就足夠。

多台節點各自編譯,簽章憑證怎麼保證一致又不外洩?

只在一個節點(通常是矽谷的簽章節點)保留憑證與描述檔,其餘節點只負責編譯輸出未簽章的 .app/.xcarchive,經 rsync 集中到簽章節點統一簽章與上傳,私鑰不落地到多台機器。

怎麼決定哪個節點擔任重負載編譯角色?

先在控制台確認各節點目前可選的機型檔位,再結合團隊成員的網路路徑與產物上傳方向來選:重編譯角色放在資源充足、對主要成員延遲低的節點,簽章與上傳角色放在出口頻寬大的節點。

需要一台獨享 Mac mini 跑建置作業?

新加坡/東京/韓國/香港/美西三地實體節點,按天起租,10 分鐘內收到 VNC/SSH 憑證。

立即租用 Mac mini