Runnerはオンラインなのに、Macを再起動したらオフラインになる。あるいは、テストは通るのに配布用ジョブだけKeychainへアクセスできない。最短の解決策は、専用の通常ユーザー、Shell executor、LaunchAgent、Xcodeの動作確認、署名情報の分離を順番に構成することです。

01

macOS GitLab Runner デプロイの判断を最初に決める

macOS GitLab Runner デプロイは、登録して管理画面に「online」と表示された時点では完了していません。実運用に入れる条件は、Xcodeを使った実ビルド、テスト、署名、再起動後の復旧、失敗後の作業ディレクトリ清掃まで確認できることです。

この手順は、手動でiOSアプリをビルドしている開発者、GitLab CIの基盤を管理するDevOpsエンジニア、長期稼働するMacを持っていない開発チーム向けです。通常のLinuxビルドだけを実行するなら、macOS Runnerを用意する必要はありません。

先に確認する配置条件

次の条件に当てはまる場合だけ、MacをRunnerにしてください。

  • Xcode、Apple SDK、iOS Simulatorが必要
  • macOS上でしか実行できないビルドまたは署名がある
  • GitLab CIから同じ開発者ツールチェーンを継続利用したい
  • ジョブを実行するコードを信頼できる
  • 証明書や秘密鍵を、対象プロジェクトと分離して管理できる

macOS RunnerのShell executorは、ジョブをRunnerユーザーの権限で実行します。異なるプロジェクトのコードや秘密情報へ到達される危険があるため、公開リポジトリや不特定多数の外部コントリビューター向けには適しません。GitLabもShell executorは信頼済みビルドに限定するよう説明しています。 Shell executorのセキュリティ注意事項

02

構成を選ぶ前に見るべき4つの境界

判断項目 推奨する構成 避けたい構成
実行ユーザー CI専用の通常ユーザー 個人の管理者アカウント
executor Xcodeを直接呼べるShell executor macOS専用ツールを隠す汎用コンテナ
Runnerの範囲 プロジェクトまたは信頼済みグループ 共有Runnerへの署名鍵配置
常駐方式 公式のLaunchAgent 非公式なLaunchDaemon改造
署名タスク 保護ブランチと保護変数に限定 分岐元が不明なコードから実行

GitLabの公式手順では、macOS RunnerはユーザーモードのLaunchAgentとして動作します。LaunchDaemonやroot実行を前提にしたLinux向けの構成を、そのままMacへ移植してはいけません。 macOSへのGitLab Runner導入手順

Macをレンタルして構築する場合も、単にCPUやメモリだけで選ばないでください。CI専用ユーザーを作成できること、Xcodeを必要な範囲で導入できること、再起動後の確認を担当者が行えることが重要です。候補を比較するときは、VpsMeshのMacレンタル構成の案内を確認し、プロジェクトのビルド負荷と運用権限を照合してください。

03

第一段階:専用ユーザーと実行範囲を用意する

Mac上に、CIジョブ専用の通常ユーザーを作成します。個人のApple ID、普段の開発用ホームディレクトリ、管理者権限をそのままRunnerに使わせない構成が安全です。

このユーザーで、GUIターミナルから作業してください。GitLabのmacOS導入手順も、Runnerを実行するユーザーでMacへサインインし、SSHセッションではなくローカルのGUIターミナルを使うよう案内しています。

Apple SiliconとIntel x86-64では、取得するRunnerバイナリが異なります。公式ページにある対象アーキテクチャ用のダウンロード手順を使い、古いブログ記事の固定バージョンや不明なスクリプトは避けてください。 Apple Silicon・Intel対応の公式インストール手順

sudo curl --output /usr/local/bin/gitlab-runner \
  "https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/binaries/gitlab-runner-darwin-arm64"

sudo chmod +x /usr/local/bin/gitlab-runner

Intel Macでは、末尾をgitlab-runner-darwin-amd64へ置き換えます。バイナリを置いた後は、Runner専用ユーザーとして登録してください。

リモートMacの設置条件も先に確認する

社内に常時稼働できるMacがない場合、リモートMacを長期CIノードとして使う方法があります。ただし、リモート接続の可否だけで判断すると、ユーザーセッションやKeychainの問題を見落とします。

SSH、VNC、Webコンソールなどの接続経路に加えて、再起動後のログイン方法、作業ディレクトリの初期化、管理者権限の範囲を確認してください。運用場所を比較するなら、VpsMeshのMac利用時のプライバシーポリシーで管理範囲と責任分界を確認してから、Runnerの登録作業へ進むと安全です。

04

第二段階:Runnerを登録し、タグを固定する

GitLabのプロジェクト、グループ、またはインスタンスからRunnerを作成し、管理画面で発行された認証情報を使います。現行の登録フローでは、Runner認証トークンはglrt-で始まる形式です。 Runner登録の公式仕様

登録例は次の形です。実際のURL、トークン、説明、タグは置き換えてください。

gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.example.invalid/" \
  --token "$RUNNER_TOKEN" \
  --executor "shell" \
  --description "macos-build-runner" \
  --tag-list "macos,xcode,ios"

タグはmacosだけにせず、Xcodeや用途を含めると誤配属を減らせます。例えば、リリース署名を行うRunnerと、署名なしテストだけを行うRunnerを別タグに分けます。

GitLab RunnerはリモートMac上で長期稼働できますか。

可能です。ただし、ユーザーセッションが維持され、Macが再起動後に対象ユーザーでログインできる構成が必要です。単にSSH接続できることや、管理画面にRunnerが表示されることだけでは不十分です。

05

第三段階:LaunchAgentとユーザーセッションを検証する

Runnerをインストールして起動します。

cd ~
gitlab-runner install
gitlab-runner start
gitlab-runner verify

macOSでは設定ファイルが~/.gitlab-runner/config.tomlに保存され、インストール時には~/Library/LaunchAgents/gitlab-runner.plistが作成されます。どちらもユーザー単位のパスです。 macOSサービスモードの公式説明

ls -l ~/.gitlab-runner/config.toml
ls -l ~/Library/LaunchAgents/gitlab-runner.plist

macOS GitLab Runnerが再起動後にオフラインになる主な理由は何ですか。

RunnerがLaunchAgentとして動き、ログイン中のユーザーセッションに依存するためです。ログアウトすると停止し、ログイン前のブート段階でLaunchDaemonのように動く設計ではありません。GitLab公式も、再起動後の可用性を保つ方法として自動ログインを案内しています。 macOS Runnerのユーザーセッション要件

ただし、自動ログインは物理的な端末管理とセキュリティのトレードオフです。署名鍵を保管する本番ノードで無条件に有効化するのではなく、データセンターの物理アクセス、ディスク暗号化、画面ロック、復旧担当者を先に決めてください。

次の順に確認します。

  1. GUIでCI専用ユーザーにログインする
  2. Runnerの状態をGitLab側で確認する
  3. SSH接続を終了してもジョブが開始できるか確認する
  4. ネットワークを短時間切断し、復帰後に再接続するか確認する
  5. Macを再起動し、ログイン後にRunnerが戻るか確認する

Runnerが再起動後に戻らない場合、まずトークンを再発行するのではなく、ユーザーセッション、LaunchAgent、設定ファイルの所有者を確認してください。

06

第四段階:GitLab CIからXcodeを最小構成で呼び出す

最初からアーカイブや配布まで実行しないでください。GitLab CIでは、リポジトリ取得、依存関係解決、署名なしビルド、テスト、アーカイブの順に小さく検証します。

stages:
  - validate
  - build
  - test
  - archive

variables:
  LC_ALL: "en_US.UTF-8"

validate:
  stage: validate
  tags:
    - macos
    - xcode
  script:
    - whoami
    - sw_vers
    - xcode-select -p
    - xcodebuild -version

build:
  stage: build
  tags:
    - macos
    - xcode
  script:
    - xcodebuild -workspace "App.xcworkspace" \
        -scheme "App" \
        -configuration Debug \
        -sdk iphonesimulator \
        -destination 'platform=iOS Simulator,name=YOUR_SIMULATOR' \
        CODE_SIGNING_ALLOWED=NO \
        build

test:
  stage: test
  tags:
    - macos
    - xcode
  script:
    - xcodebuild test \
        -workspace "App.xcworkspace" \
        -scheme "App" \
        -destination 'platform=iOS Simulator,name=YOUR_SIMULATOR'

ここで確認するのは、Runnerがオンラインかどうかではありません。xcode-select -p、Xcodeのバージョン、SDK、シミュレーター名、終了コード、保存されたログです。Xcodeのビルド設定では、CODE_SIGN_IDENTITYがKeychain内の有効な証明書を参照します。証明書がない、または無効ならビルドエラーになります。 Xcodeビルド設定リファレンス

GitLab CIでXcodeビルドを実行する際に最初に分けるべき作業は何ですか。

署名なしのコンパイルとテストを先に通し、その後にアーカイブと配布署名を接続します。これにより、Xcode、SDK、依存関係の問題と、証明書・プロビジョニング・Keychainの問題を切り分けられます。

Xcodeの初回起動、追加コンポーネント、依存パッケージの取得は、Runner専用ユーザーで一度確認してください。個人ユーザーでしか準備していない環境では、CIの実行時に別のホームディレクトリを参照して失敗します。

07

第五段階:証明書とKeychainを公開ジョブから分離する

テスト用ジョブと配布用ジョブでは、必要な権限が違います。テストでは署名を無効化できる場合がありますが、配布では証明書、秘密鍵、プロビジョニング情報、配布用認証情報が必要です。

Appleの説明では、証明書と秘密鍵を組み合わせたIdentityは秘密として管理され、Keychainに保存できます。 Appleの証明書・鍵・Trust Services

運用上は、次の分離が基本です。

  • 配布用Runnerをプロジェクトまたは信頼済みグループ専用にする
  • 署名関連の変数を保護し、保護ブランチでのみ利用する
  • 証明書と秘密鍵をリポジトリへコミットしない
  • 一時Keychainを作成し、ジョブ終了後に削除する
  • 外部コントリビューターのコードを配布用Runnerへ流さない
  • 失敗時に作業ディレクトリ、ログ、生成物へ秘密情報が残っていないか確認する

Keychainは暗号鍵や証明書を保存する仕組みですが、アクセス制御が自動的にCIの安全性を保証するわけではありません。Keychainのアクセスグループは、同じ開発チームに属するアプリ間で共有範囲を設定する仕組みです。 Keychain共有の公式説明

署名ジョブを実行できるRunnerへ、マージリクエストから変更可能なスクリプトを無条件に送る構成は避けてください。Shell executorではジョブがRunnerユーザーの権限で動作します。

08

本番稼働前に実ジョブで行う最終検収

空のプロジェクトで成功しても、本番CIの品質は判断できません。最初の運用週は、実際のiOSプロジェクトで次を確認します。

  • Gitリポジトリの取得が成功する
  • 依存関係の解決結果が再現する
  • 署名なしビルドとテストが成功する
  • 配布用アーカイブが想定した証明書を使う
  • 失敗後に作業ディレクトリが肥大化しない
  • キャッシュが古いSDKや中間生成物を持ち込まない
  • 同時実行でDerivedDataや一時Keychainが衝突しない
  • 再起動後にRunnerが復帰する
  • ログ、成果物、終了コードをGitLab側で確認できる

判断は次のように分けてください。

  • 継続:実ジョブ、署名、再起動復旧がすべて再現する
  • 清掃して継続:ビルドは成功するが、キャッシュや作業ディレクトリの増加が見られる
  • Runnerを追加:待ち時間や署名ジョブの競合が発生する
  • 手動へ戻す:Keychain、復旧、秘密情報の境界を説明できない

Runnerの設定を変更した場合、設定ファイルは非root実行では~/.gitlab-runner/にあります。変更後はgitlab-runner verifyと実ジョブで確認してください。設定の検証コマンドは構文確認の助けになりますが、エラーがないことだけで完全な動作を保証するものではありません。 高度なRunner設定

09

現在の構成とリモートMacを比較して決める

Linuxサーバーや手元のWindows環境だけで運用すると、XcodeとApple SDKを実行できない、署名用Keychainを維持できない、iOS Simulatorを本番に近い形で検証できないという制約があります。Mac miniを購入する方法もありますが、初期投資、故障時の交換、設置場所、長期休止中の固定費が残ります。

一方、リモートMacは実機のmacOS環境を継続利用でき、必要な期間だけCIノードを確保しやすい方法です。ただし、物理デバイス接続や長期の高負荷処理では、専用機を購入した方が合う場合もあります。

短期の移行、リリース前の増設、チームに常時稼働Macがない場合は、VpsMeshのレンタル構成を候補に入れると、購入前に実ジョブで検証できます。地域との接続遅延や運用担当者のアクセス経路も確認したい場合は、VpsMeshの東京リージョンのMac構成を比較対象にしてください。

手元のMacやLinuxサーバーを使い続ける場合は、物理ポートを直接利用できることや、既存の社内ネットワークへ接続しやすいことが利点です。ただし、Mac本体の故障対応、常時稼働、ユーザーセッションの復旧、Xcode環境の再構築を自分で担う必要があります。

そのため、まずは署名なしビルドと実際の配布ジョブを一定期間動かし、Runnerの待ち時間、再起動復旧、Keychainの扱いを記録してください。長期購入の前に運用負荷を確認したい場合や、リリース期間だけMacノードを増やしたい場合は、リモートMacの方が判断しやすいケースがあります。