主機無法長期在線、沒有管理員權限 → 不要部署生產 Runner。
需要 macOS 建構節點 → 選擇可持續連線的真實 Apple Silicon 遠端 Mac,先註冊,再配置系統服務與安全邊界。
GitHub 官方要求自托管 Runner 能透過出站 HTTPS 連線至 GitHub;其網路需求文件列出的最低傳輸能力為上下行各 70 Kbps,並需要使用 443 埠。因此,遠端 Mac 可以作為生產 Runner,但「頁面顯示 Online」只代表連線成功,不代表它已具備安全、可恢復、可驗證的生產條件。(GitHub 自托管 Runner 網路需求)
這篇文章適合三類讀者:需要為 iOS 或 macOS 專案增加持續整合節點的移動開發者;需要統一管理組織級建構資源、標籤與密鑰權限的 DevOps 工程師;以及需要持久快取、內網存取或自訂工具鏈的研發團隊。
遠端 Mac 的准入條件
主機能力核對
部署前先把遠端 Mac 當成一台需要長期維運的伺服器,而不是臨時測試桌面。你至少要確認以下條件:
- [ ] 可持續開機,且不會因使用者登出、SSH 結束或螢幕鎖定而停止 Runner。
- [ ] 你擁有管理員權限,能安裝 Runner、建立服務、調整工作目錄與檢查系統日誌。
- [ ] macOS 版本符合 GitHub 當前支援範圍。GitHub 文件目前列出的 macOS 最低版本為 macOS 11.0 Big Sur;Apple Silicon 的 ARM64 Runner 狀態仍應以 GitHub 新增 Runner 頁面當下顯示為準。(GitHub 自托管 Runner 支援平台)
- [ ] 主機可以對外建立 HTTPS 連線,並能連到工作流程實際需要的套件庫、原始碼服務、製品儲存區或簽名服務。
- [ ] 磁碟空間足以容納原始碼、DerivedData、套件快取、模擬器資料與建構製品;具體容量應由你的專案清理策略與工具鏈測量,不要用一個固定數字代替驗證。
- [ ] 處理器架構與專案依賴一致,尤其是需要原生 Apple Silicon 工具鏈、模擬器或 ARM64 套件的工作流程。
系統與權限檢查
在遠端 Mac 執行:
uname -m
sw_vers
df -h
id -Gn
uname -m 用來確認架構,sw_vers 用來記錄系統版本,df -h 用來觀察可用硬碟空間,id -Gn 則協助你確認目前帳戶是否具備所需群組權限。這些輸出應保存到首次驗收記錄,而不是只在終端機看過一次。
註冊層級選擇
單一專案先試跑時,使用倉庫級 Runner較容易控制影響範圍;如果多個私有倉庫需要共用同一套 macOS 工具鏈,則應從組織級 Runner與 Runner 群組開始。GitHub 支援在倉庫、組織或企業層級加入自托管 Runner,而組織級 Runner 可以服務多個倉庫,因此權限範圍必須先於安裝步驟決定。(GitHub 新增自托管 Runner)
GitHub Actions 自托管 Runner 的部署流程
第一階段:建立專用帳戶
不要直接使用你平時的桌面帳戶執行 CI。建議建立一個只服務建構任務的非日常開發帳戶,並將以下內容分開管理:
- Runner 安裝目錄與工作目錄;
- 原始碼快取、套件快取與建構製品;
- Apple 開發者憑證、描述檔與簽名用密鑰;
- SSH 金鑰、部署權杖與內網服務存取憑證;
- 允許使用此 Runner 的倉庫與分支。
這樣做不是為了形式上的帳戶隔離,而是降低個人登入狀態、瀏覽器資料、SSH 金鑰和 CI 程式碼共存於同一主機的風險。
第二階段:從 GitHub 控制台取得指令
在倉庫或組織的 Settings → Actions → Runners 中選取新增自托管 Runner,然後選擇 macOS 與實際架構。GitHub 會根據當下的架構與版本提供下載指令;不要把網路文章中的版本號、下載網址或註冊權杖直接複製到生產環境。註冊權杖是由控制台即時產生的限時憑證,官方文件說明其有效期為 1 小時。(GitHub 新增自托管 Runner)
典型操作順序如下,尖括號內容必須以 GitHub 控制台產生的指令替換:
mkdir actions-runner && cd actions-runner
# 貼上 GitHub 控制台針對 macOS 與實際架構產生的下載指令
# 解壓縮後執行控制台提供的 config 指令
./config.sh --url <REPOSITORY_OR_ORGANIZATION_URL> \
--token <TIME_LIMITED_REGISTRATION_TOKEN> \
--name <RUNNER_NAME> \
--labels <CUSTOM_LABELS>
完成後,確認終端機出現已連線並等待工作訊息,再回到 GitHub 控制台檢查名稱、作業系統、架構、標籤與狀態。GitHub 的標籤文件指出,自訂標籤可在初次設定時透過 config 指令加入,也可在後續透過管理介面或 API 調整。
第三階段:配置開機自動執行
如果你只在 SSH 連線期間手動執行 ./run.sh,離開終端機後 Runner 便可能停止。macOS 應在完成註冊後,再使用官方產生的 svc.sh 安裝服務:
sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh status
GitHub 說明,macOS 服務由 launchd 管理;服務名稱與檔案位置可能依組織、倉庫及 Runner 名稱產生,因此不要自行猜測 plist 檔案名稱。可以先查看:
cat .service
sudo ./svc.sh status
完成後至少做兩次驗證:先離開 SSH 工作階段,再重新連線檢查;接著安排一次主機重啟,確認服務能自行恢復。
macOS 自托管 Runner 怎樣設定開機自動執行?
重點不是把 Runner 放進某個登入項目,而是使用註冊後產生的服務腳本,並以 svc.sh status、GitHub 控制台狀態及實際工作流程三方交叉驗證;若只看到桌面登入後能執行,仍不能算完成。
第四階段:設定標籤路由
為 Apple Silicon 遠端 Mac 設定清楚、可讀、與實際能力一致的標籤,例如:
runs-on: [self-hosted, macOS, ARM64, ios-build]
標籤不是裝飾,而是工作流程的路由條件。GitHub 會尋找同時符合 runs-on 標籤與 Runner 群組的線上閒置節點;若找不到匹配節點,工作會保持排隊,直到節點恢復或工作逾時。
請避免使用與實際能力不符的標籤,例如把 Intel 主機標成 ARM64,或把沒有簽名權限的節點標成 release-signing。標籤應反映可驗證條件,而不是團隊希望它具備的能力。
首次工作流程與驗收證據
最小化工作流程
先不要立即執行完整簽名與發佈流程,應先用最小工作流程驗證路由、架構和工具鏈:
name: runner-check
on:
workflow_dispatch:
jobs:
inspect:
runs-on: [self-hosted, macOS, ARM64, ios-build]
steps:
- uses: actions/checkout@v4
- name: Inspect host
run: |
uname -m
sw_vers
xcode-select -p
xcodebuild -version
git --version
Apple 文件指出,xcodebuild 等工具隨完整 Xcode 提供;單獨安裝 Command Line Tools 並不等於已安裝完整 Xcode,因此涉及 Xcode 專案時,必須確認 xcode-select 指向預期的 Xcode。(Apple Developer:安裝 Command Line Tools)
你應把驗收拆成兩層:
- Runner 連通驗收:工作能被正確標籤路由,主機能執行 Shell 指令,系統與架構輸出符合預期。
- 專案建構驗收:依賴安裝、快取、測試、簽名與製品上傳均能完成,且產物可被後續流程使用。
選型對比
| 方案 | 適合情境 | 優點 | 主要限制 | 生產判斷 |
|---|---|---|---|---|
| 倉庫級遠端 Mac Runner | 單一私有專案先試跑 | 權限與故障範圍較小 | 多倉庫共享不方便 | 先用於驗證 |
| 組織級遠端 Mac Runner | 多個私有倉庫共用工具鏈 | 可配合 Runner 群組與標籤管理 | 權限錯配會擴大影響面 | 適合集中維運 |
| GitHub 託管 macOS Runner | 不需要持久快取或固定主機狀態 | 每次工作環境較乾淨 | 自訂工具、內網與持久狀態受限 | 適合一般建構 |
| 持久化遠端 Mac Runner | 需要 Apple Silicon、內網或固定工具鏈 | 可保留工具與快取,便於長期 CI | 主機會殘留工作痕跡,安全責任由你承擔 | 僅限受控私有工作流 |
GitHub 明確提醒,自托管 Runner 不保證每次工作都在乾淨、隔離的暫存環境中;未受信任程式碼可能持續影響主機,因此公共倉庫的 Pull Request 不應直接進入持久化 Runner。(GitHub Actions 安全使用指南)
安全加固與長期維運
工作目錄與密鑰邊界
持久化 Runner 不會自動在每次工作後清空整台主機。你需要在工作流程中明確處理:
- 工作開始前移除上一輪未完成的暫存檔;
- 區分可重用的套件快取與不得殘留的簽名資料;
- 工作結束後刪除描述檔、臨時憑證與解密後的設定檔;
- 使用 GitHub Environments、最小權限權杖與受控分支;
- 將簽名與發佈工作限制於可審核的私有工作流程。
自托管 Runner 能否安全用於公共倉庫?
不應把公共倉庫的未受信任 Pull Request 直接送到持久化遠端 Mac。GitHub 的安全指南指出,攻擊者可能透過工作流程取得主機上的敏感資料、權杖或網路存取能力;即使加入環境審核,也不能把持久化主機變成乾淨隔離環境。
離線排查順序
遠端 Mac Runner 顯示離線時怎樣排查?
按照由近至遠的順序處理,避免一開始就刪除並重新註冊:
- 確認主機仍在線,SSH 是否可連線。
- 執行
sudo ./svc.sh status,確認服務是否仍在執行。 - 使用
launchctl檢查 macOS 的launchd服務。 - 查看 Runner 目錄中的服務檔案與日誌,確認是否為權限、路徑或環境變數問題。
- 測試出站 HTTPS 與 DNS,尤其是 GitHub 下載、套件與製品所需網域。
- 回到 GitHub 控制台確認 Runner 是否為 Offline、Busy 或已被移除。
GitHub 將 Offline 定義為主機離線、Runner 程式未執行,或 Runner 無法與 GitHub 通訊;因此「重啟服務」與「檢查網路」應分開驗證。(GitHub Runner 監控與疑難排解)
上線檢查清單
- [ ] 註冊層級已確認:單專案使用倉庫級,多倉庫共享使用組織級。
- [ ] Runner 使用獨立帳戶,沒有混入日常瀏覽器登入態與私人 SSH 金鑰。
- [ ]
uname -m、macOS 版本、Xcode 路徑與工具版本已記錄。 - [ ]
runs-on能以標籤準確命中 Apple Silicon macOS 建構節點。 - [ ] SSH 結束後 Runner 仍在線。
- [ ] 主機重啟後服務能自動恢復。
- [ ] 受控分支已完成測試、簽名與製品上傳驗證。
- [ ] 公共 Pull Request、未審核分支與持久化 Runner 已隔離。
- [ ] 已建立磁碟清理、服務日誌、Runner 更新與停用流程。
- [ ] 已演練重啟恢復、失敗工作重跑、磁碟清理與節點撤除。
Runner 應用程式會依 GitHub 的更新政策取得新版本;官方參考文件指出,閒置 Runner 也會在發布後的週期內嘗試更新,而遇到必要的安全更新時,服務可能暫停向未更新的 Runner 派送工作。版本號與下載指令應以官方 Runner 發布頁及新增 Runner 頁面即時內容為準。
如果你仍在整理整套遠端 Mac 開發環境配置,建議先把 Runner 當成獨立的 macOS 建構節點,而不要把它當成可隨意共用的桌面;涉及長期快取、內網連線或簽名任務時,也應同步檢查服務條款與權限責任。
對比之下,臨時用個人 Mac 跑 CI 的缺點是主機不一定長期在線、工作目錄容易與日常檔案混用,而且重啟、睡眠或登入狀態都可能令工作失敗;自行購買 Mac mini 則需要承擔硬體採購、網路、電力、遠端維護與故障恢復。若你需要的是臨時建構環境、測試節點或可按週期使用的 Apple Silicon 主機,可先查看 KVMFLUX 的遠端 Mac 租賃方案,再依本文的註冊、標籤、安全與重啟驗收流程部署;但若你需要長期固定負載、實體 USB 設備或完全掌控機房網路,自購並自行託管仍可能更合適。