Macビルドサーバーの高可用性を確保するなら、企業のリリース処理を単一ノードに任せず、主系と検証済み待機系の2系統で運用します。今週は、実際のリリース用パイプラインを1本選び、主系の受付停止から待機系で署名付き成果物を出すまでを記録してください。

対象は、少数のMacビルドノードを管理するIT責任者、iOS CI/CDの可用性とキューを担当する開発生産性責任者、災害対策費用やSLAを審査するCTO・技術責任者です。単に「ノードがオンラインか」を確認するのではなく、障害時に誰が、何を、どの証拠で復旧と判断するかまで決めます。

01

単一ノードの稼働と、リリース継続性は別物です

リリース中に唯一のMacが停止すると、ジョブはキューに残っていても出荷は進みません。ホストが24時間稼働していることは、ビルド、署名、依存関係の取得、成果物の保存まで継続できることを意味しません。

最初に次の3つを分けて定義します。

  • 復旧時間の目標:障害検知から、待機系がジョブを受け付けるまでの時間
  • 失ってよいビルド状態:実行中ジョブを再実行するのか、途中成果物を再利用するのか
  • リリース阻害範囲:全製品が止まるのか、特定ブランチや特定Xcode系統だけが止まるのか

単一ノード、冷却状態の待機機、常時検証する温存機、同時稼働する2系統には、それぞれ適用範囲があります。多くの企業では、最初から完全な二重化を目指すより、主系を安定運用しながら待機系で実プロジェクトを定期検証する方法が、監査可能性と費用のバランスを取りやすいです。

GitHub Actionsでは、ジョブはRunnerのラベルやグループに基づいて割り当てられます。オンラインかつ待機中のRunnerが見つからなければジョブはキューに残り、一定時間を超えると失敗します。したがって、待機ノードは「存在するMac」ではなく、「正しいラベルでジョブを受け取れるMac」として設計します。(docs.github.com)

02

障害別に見る、止まる範囲と切り替え条件

停電・OS停止なら、受付停止から始めます

主系が停止した場合、最初にCI側で新規ジョブの投入を止めます。実行中ジョブ、未処理キュー、最後に成功したコミット、成果物の保存先を記録します。

その後、待機系のRunner状態、リポジトリへの接続、依存先への接続、署名情報、Keychainの状態を確認します。待機系で突然セットアップを始めると、障害対応中に別の変更が入り、原因と復旧状態が分からなくなります。

macOSには、電源障害後に自動起動する設定があります。ただし、自動起動してもFileVaultの解除やユーザーセッションの確立まで完了するとは限りません。Appleの公式手順でも、SSH経由の再起動と電源障害後の自動起動は別の設定として扱われています。(support.apple.com)

予定メンテナンスでも、待機系を使います

macOS更新、Xcode移行、SDK追加、Swift Package更新は、停止時間を予約すれば解決する問題ではありません。更新後に署名、シミュレーター、依存パッケージ、アーカイブ出力のどこかが変わると、公開直前に初めて問題が表面化します。

主系は安定版を維持し、待機系で次のツールチェーンを先行検証します。Xcode 26の公式要件では、動作するmacOSの条件が指定されています。XcodeとmacOSを個別に更新するのではなく、対応する組み合わせとして管理してください。(developer.apple.com)

発売ピークは、性能不足か台数不足かを分けます

キューの増加だけを見て高性能なMacへ交換すると、同時実行数の問題を解決できない場合があります。反対に、ビルド時間が伸びていないのに待ち時間だけ増えているなら、ノード数やジョブのルーティングが原因かもしれません。

最低限、次の傾向を同じ期間で確認します。

  • ジョブ投入から開始までの待ち時間
  • ジョブごとの実行時間
  • 同時実行数と失敗率
  • Xcode、依存取得、署名、成果物転送の各工程時間

単発のベンチマークではなく、通常日とリリース日を比較します。GitHub ActionsではラベルにmacOSARM64などを組み合わせてRunnerを選べますが、実際のルーティング条件は利用中のCIサービスの公式仕様に合わせて確認します。(docs.github.com)

03

第一歩:主系と待機系の環境基準を固定します

待機系を作る前に、環境を「人が覚えている設定」から「確認できる基準表」に変えます。Xcodeの表示バージョンだけでは不十分です。macOS、SDK、Swift Package、証明書、スクリプト、Runner設定を一つの変更記録にまとめます。

確認対象 主系で記録する内容 待機系の合格条件
Mac構成 Apple Siliconか、アーキテクチャ、ストレージ構成 対象ジョブの要求条件を満たす
macOS 正確なバージョンと更新履歴 Xcodeの公式要件に適合
Xcode バージョン、ビルド番号、インストール済みSDK 同じプロジェクトを同じ設定で実行
依存関係 Package.resolved、Lockfile、補助ツール 固定ファイルから再構築できる
CI設定 Runnerラベル、グループ、権限 待機系へ明示的にルーティングできる
成果物 Archive、IPA、ログ、ハッシュの保存先 主系停止後も取得できる

Appleの署名仕様では、証明書とProvisioning Profileは別の役割を持ちます。プロファイルに含まれる条件と証明書の対応を確認し、証明書ファイルだけをコピーして成功したと判断しないでください。(developer.apple.com)

04

第二歩:署名情報をホストから切り離します

災害対策で最も見落とされるのが、コンパイルはできるが署名できない状態です。証明書、秘密鍵、Provisioning Profile、Appleアカウント権限、Keychain、SSH鍵、プライベート依存先の認証情報を別々に台帳化します。

責任者と失効経路も記録します。たとえば、配布証明書の期限切れは開発チーム、秘密鍵の保管はセキュリティ担当、依存先のSSH鍵はプラットフォーム担当というように、復旧作業を一人の担当者に集中させません。

CI変数へ秘密情報を保存する場合も、マスクだけで安全とは限りません。保護ブランチや保護タグに限定し、可能なら外部の秘密情報管理基盤を使います。ログ出力やデバッグ設定で秘密情報が露出する可能性もあるため、復旧訓練ではログとアーティファクトの公開範囲まで確認します。(docs.gitlab.com)

注意:主系のユーザーディレクトリを丸ごと待機系へコピーする方法は、秘密鍵、キャッシュ、個人設定、不要なセッション情報まで複製します。復旧性を高めるのではなく、監査対象を増やす結果になりやすいため、宣言的なセットアップと限定的な資格情報配布を優先します。

05

第三歩:切り替え手順をジョブ単位で検証します

実際の切り替えは、次の順番に固定します。

  1. 主系の新規ジョブ受付を停止します。
  2. 実行中ジョブ、キュー、最後の成功コミットを記録します。
  3. 待機系のRunnerがオンラインで、正しいラベルを持つことを確認します。
  4. Xcode、SDK、依存関係、証明書、秘密鍵、Provisioning Profileを検査します。
  5. 対象ブランチを待機系へルーティングします。
  6. テスト、Archive、署名、成果物保存を順番に実行します。
  7. ログ、生成物、署名結果、手動介入点を記録します。

GitLabを使う場合は、Runnerのタグと保護された変数の設計を公式仕様に合わせます。GitHub Actionsのラベル方式を、そのまま別のCIサービスへ移植しないでください。ジョブの選択、保護設定、キュー処理はサービスごとに確認が必要です。(docs.gitlab.com)

06

待機構成と費用を、固定負荷とピーク負荷で分けます

常時必要なビルド量と、リリース時だけ増える処理量を同じ資産で持つ必要はありません。固定負荷には長期運用する主系と待機系を割り当て、Xcode更新やピーク時には一時的な遠隔Macを追加する構成も候補になります。

構成 向いている場面 弱点 判断条件
単一ノード 小規模な検証専用 障害時に切り替え先がない 公開リリースを依存させない
冷却待機 低頻度の障害対策 環境差分が蓄積しやすい 定期的な実ビルドが可能
検証済み待機 多くの企業の初期構成 待機系の維持工数が必要 実プロジェクトを定期実行
2系統同時稼働 高い継続性や複数製品 費用と運用が増える 並列負荷と停止許容範囲が明確
一時ノード追加 発売ピーク、移行期間 事前の接続・環境検証が必要 追加容量の調達手順が確立

費用は、次の変数で計算します。

費用項目 計算に使う変数 確認する内容
基礎容量 主系台数、待機系台数、利用期間 常時確保が必要か
ピーク容量 追加ノード数、利用時間、ピーク回数 リリース日だけ増やせるか
運用工数 更新、監視、切り替え訓練の時間 内製担当者の工数単価
障害損失 停止時間、再実行数、公開延期の影響 金額化できる業務影響
秘密情報管理 保管、ローテーション、監査の工数 証明書と鍵を誰が管理するか

自社設備を購入する場合は、購入費だけでなく、予備機の保管、故障交換、OSとXcodeの検証、電源・ネットワーク、廃棄や更新を含めます。短期の移行やピーク対応では、Macの購入条件を確認するための比較ガイドを使い、購入が適する期間と一時利用が適する期間を分けて検討します。

07

復旧演習では、結果より証拠を残します

演習は「待機系でビルドできた」で終了させません。主系の受付停止から、成果物の検証、主系への復帰までを一つの記録にします。

演習段階 合格条件 残す証拠
主系停止 新規ジョブが主系へ流れない CI設定、時刻、キュー画面
待機系起動 Runnerがオンラインになる Runnerログ、ラベル情報
環境確認 Xcodeと依存関係が基準表と一致 バージョン出力、Lockfile
署名確認 Archiveと署名付き成果物を生成 ビルドログ、署名検証結果
成果物確認 保存先から取得できる IPA、ハッシュ、保存ログ
復帰確認 主系復旧後に誤ルーティングがない ルーティング設定、復帰ログ
事後確認 人工操作と失敗理由を説明できる 演習報告、改善チケット

合格しなかった項目は、待機系を「利用可能」と表示しないでください。特に、遠隔接続はできるがRunnerが起動しない、Macは起動したがFileVault解除で止まる、ビルドは成功するが署名鍵がない、といった部分障害を分けて記録します。

08

災害対策の導入を判断するチェックリスト

  • [ ] 主系の新規ジョブ受付を停止する手順がある
  • [ ] 待機系のRunnerラベルまたはタグを確認できる
  • [ ] macOS、Xcode、SDK、依存関係を基準表で固定している
  • [ ] Apple Silicon要件とXcodeの対応条件を確認している
  • [ ] 証明書、秘密鍵、Provisioning Profileの責任者を分けている
  • [ ] KeychainとFileVault解除の手順を実機で確認している
  • [ ] SSHやプライベート依存先の認証情報を再発行できる
  • [ ] 待機系で実プロジェクトの署名付きビルドを実行している
  • [ ] 成果物、ログ、ハッシュを主系以外から取得できる
  • [ ] リリースピーク時の追加ノード手順を持っている
  • [ ] 復旧演習の失敗原因と人工操作を記録している
  • [ ] SLAや復旧目標を実測結果に基づいて見直している
09

FAQ

Macビルドサーバーが停止したときの切り替え

主系の受付を止め、キューと実行中ジョブを記録してから、待機系のRunner、環境、署名情報を確認します。待機系で実際のリリース相当ビルドを行い、成果物と署名結果まで検証して完了とします。

企業のiOS CI/CDに必要なMacの台数

開発者数ではなく、同時実行数、ピーク時の待ち時間、Xcode系統、停止許容範囲で決めます。最初の基準は主系1台と検証済み待機系1台ですが、複数製品や複数ツールチェーンを扱う場合は環境単位で分けます。

Xcodeと依存環境の同期

主系のディレクトリを複製せず、XcodeとmacOSのバージョン、Lockfile、Package.resolved、セットアップスクリプトを管理します。待機系では定期的に実プロジェクトをビルドし、同一の成果物条件を満たすか確認します。

署名証明書の安全な移行

証明書、秘密鍵、Provisioning Profile、Keychain、Appleアカウント権限を別々に管理し、保管責任者と失効手順を台帳化します。秘密情報を含むユーザーディレクトリ全体をコピーせず、限定的に配布して署名付きArchiveまで検証します。

遠隔Macを待機ノードにする条件

遠隔Macでも、Runner接続、ジョブルーティング、依存先への接続、再起動後のサービス復旧、署名情報、ログ取得を事前に検証できれば候補になります。現有設備で予備機を長期保管できない場合は、週単位または月単位で追加し、実案件の切り替え訓練に使います。

10

今週の災害対策アクション

まず、最も重要なリリースパイプラインを1本選び、主系の受付停止、待機系へのルーティング、署名付き成果物の生成、ログ保存までを実行します。結果が不合格なら、冷却待機のままにせず、環境同期、秘密情報、Runner接続のどこが不足しているかを修正してください。

自社のMacを追加購入する方法は、長期間にわたり安定した高負荷があり、物理機器を社内で管理できる場合に向きます。一方で、予備機の保管、故障対応、Xcode更新、ピーク時だけ必要な容量まで固定費になりやすい点が弱点です。現有設備で待機系を維持できない場合は、MESHLAUNCHの遠隔Mac環境を一時的なCI/CD災害対策ノードとして実案件で検証し、復旧手順とピーク容量を確認してから、購入台数や長期契約を決めるのが安全です。