ガイド - CI/CD

Mac Mini M4 で GitHub Actions セルフホストランナーを構築する方法

専用 Mac Mini M4 で GitHub Actions セルフホストランナーを構築するステップバイステップガイド。高速な iOS ビルド、Apple Silicon ネイティブ、そして GitHub ホスト型 macOS ランナーと比べて最大 10 倍のコスト削減。

読了時間 30 分 2026 年 3 月更新

1. なぜセルフホストの Mac ランナーを使うのか?

GitHub ホスト型の macOS ランナーは便利ですが高価です。1 分あたり$0.08で、月に 75 時間のビルドを実行するチームは約$360を支払うことになります。MyRemoteMac の専用 Mac Mini M4 なら、ビルド分数が無制限で月額$85であり、同等(またはそれ以上)のハードウェアをわずかなコストで利用できます。

項目 GitHub ホスト型ランナー MyRemoteMac セルフホスト
コスト $0.08/分(75 時間で約$350/月) 月額$85(無制限の分数)
アーキテクチャ Intel x86(一部 M1) Apple M4(最新)
ビルド速度 約 12 分(中規模プロジェクト) 約 4 分(同じプロジェクト)
永続的なキャッシュ なし(使い捨て) あり(永続的なディスク)
カスタムソフトウェア 限定的 完全な root アクセス
同時ジョブ数 5(無料)/ 20(有料) 無制限(自分のハードウェア)

主なメリット: ランナーが永続的であるため、DerivedData、SPM キャッシュ、CocoaPods がビルド間で保持されます。これだけでも、毎回ゼロから始まる使い捨ての GitHub ホスト型ランナーと比べて、ビルド時間を 50〜70% 短縮できます。

2. 前提条件

始める前に、次のものが揃っていることを確認してください。

  • MyRemoteMacMac Mini M4 サーバー(月額$85から)
  • リポジトリまたは組織への管理者アクセス権を持つ GitHub アカウント
  • Mac Mini への SSH アクセス(MyRemoteMac のサブスクリプションに付属します)
  • Apple Developer アカウント(コード署名とプロビジョニングプロファイル用)
  • YAMLターミナルコマンドの基本的な知識

3. ステップ 1: Mac Mini に SSH 接続して Xcode をインストールする

まず、Mac Mini M4 に SSH で接続します。MyRemoteMac サーバーをセットアップした際に認証情報を受け取っているはずです。

SSH で接続する

# Connect to your Mac Mini M4
ssh admin@your-server-ip

# Verify you're on Apple Silicon
uname -m
# Expected output: arm64

# Check macOS version
sw_vers
# ProductName:    macOS
# ProductVersion: 15.2
# BuildVersion:   24C101

Xcode Command Line Tools をインストールする

# Install Command Line Tools
xcode-select --install

# Accept the license agreement
sudo xcodebuild -license accept

# Verify installation
xcode-select -p
# /Library/Developer/CommandLineTools

Xcode(フルバージョン)をインストールする

iOS ビルドには Xcode アプリケーションの完全版が必要です。ヘッドレスサーバーにインストールする最も速い方法は xcodes を使うことです。

# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Add Homebrew to PATH
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"

# Install xcodes CLI tool
brew install xcodes

# List available Xcode versions
xcodes list

# Install the latest stable Xcode
xcodes install 16.2

# Set it as the active Xcode
sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer

# Verify
xcodebuild -version
# Xcode 16.2
# Build version 16C5032a

iOS シミュレーターをインストールする

# Install the iOS 18 simulator runtime
xcodebuild -downloadPlatform iOS

# Verify simulator availability
xcrun simctl list runtimes
# == Runtimes ==
# iOS 18.2 (18.2 - 22C150) - com.apple.CoreSimulator.SimRuntime.iOS-18-2

4. ステップ 2: GitHub Actions ランナーをインストールする

次に、GitHub Actions ランナーエージェントをダウンロードして設定します。GitHub 上でリポジトリに移動し、Settings > Actions > Runners > New self-hosted runner に進んで、macOS + ARM64 を選択します。

ダウンロードして設定する

# Create a directory for the runner
mkdir -p ~/actions-runner && cd ~/actions-runner

# Download the latest runner package (ARM64)
curl -o actions-runner-osx-arm64-2.321.0.tar.gz -L \
  https://github.com/actions/runner/releases/download/v2.321.0/actions-runner-osx-arm64-2.321.0.tar.gz

# Extract the package
tar xzf actions-runner-osx-arm64-2.321.0.tar.gz

# Configure the runner
# Replace YOUR_TOKEN with the token from GitHub Settings
./config.sh --url https://github.com/YOUR_ORG/YOUR_REPO \
  --token YOUR_TOKEN \
  --name "mac-mini-m4-runner" \
  --labels "self-hosted,macOS,ARM64,M4" \
  --work "_work"

# Test the runner interactively first
./run.sh

永続的な launchd サービスとしてインストールする

エージェントを対話的に実行するのはテストには問題ありませんが、本番では起動時に自動的に開始し、クラッシュしても再起動する必要があります。GitHub は macOS 向けの組み込みサービスインストールスクリプトを提供しています。

# Install as a launchd service
cd ~/actions-runner
sudo ./svc.sh install

# Start the service
sudo ./svc.sh start

# Check the service status
sudo ./svc.sh status
# Expected: "active (running)"

# View the launchd plist (for reference)
cat /Library/LaunchDaemons/actions.runner.*.plist

これでサービスは起動時に自動的に開始し、プロセスが停止しても再起動するようになります。ランナーがリポジトリの Settings > Actions > Runners ページに「Idle」として表示されることを確認できます。

複数のリポジトリ向けにランナーを設定する(組織レベル)

# For an organization-level runner, use the organization URL:
./config.sh --url https://github.com/YOUR_ORG \
  --token YOUR_ORG_TOKEN \
  --name "mac-mini-m4-org-runner" \
  --labels "self-hosted,macOS,ARM64,M4" \
  --runnergroup "Default" \
  --work "_work"

# This allows ALL repositories in your organization to use this runner

5. ステップ 3: iOS ビルドワークフローを作成する

リポジトリ内の .github/workflows/ios-build.yml にワークフローファイルを作成します。このワークフローは、セルフホストの Mac Mini M4 ランナー上で実行されます。

name: iOS Build & Test

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64, M4]

    env:
      SCHEME: "MyApp"
      DESTINATION: "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2"

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Select Xcode version
        run: |
          sudo xcode-select -s /Applications/Xcode-16.2.app/Contents/Developer
          xcodebuild -version

      - name: Resolve Swift Package Dependencies
        run: |
          xcodebuild -resolvePackageDependencies \
            -scheme "$SCHEME" \
            -clonedSourcePackagesDirPath .spm-cache

      - name: Build the app
        run: |
          xcodebuild build \
            -scheme "$SCHEME" \
            -destination "$DESTINATION" \
            -clonedSourcePackagesDirPath .spm-cache \
            -derivedDataPath DerivedData \
            | xcbeautify

      - name: Run unit tests
        run: |
          xcodebuild test \
            -scheme "$SCHEME" \
            -destination "$DESTINATION" \
            -clonedSourcePackagesDirPath .spm-cache \
            -derivedDataPath DerivedData \
            -resultBundlePath TestResults.xcresult \
            | xcbeautify

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results
          path: TestResults.xcresult

リリースビルドのためのコード署名を追加する

TestFlight や App Store へのデプロイには、コード署名のステップを追加します。証明書とプロビジョニングプロファイルは GitHub Secrets として保存してください。

  deploy:
    needs: build
    runs-on: [self-hosted, macOS, ARM64, M4]
    if: github.ref == 'refs/heads/main'

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install certificate and provisioning profile
        env:
          BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
          P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
          BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
          KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
        run: |
          # Create a temporary keychain
          KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
          security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
          security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
          security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH

          # Import certificate
          CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
          echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
          security import $CERTIFICATE_PATH -P "$P12_PASSWORD" \
            -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
          security list-keychain -d user -s $KEYCHAIN_PATH

          # Install provisioning profile
          PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
          echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
          cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles

      - name: Build for distribution
        run: |
          xcodebuild archive \
            -scheme "MyApp" \
            -archivePath DerivedData/MyApp.xcarchive \
            -destination "generic/platform=iOS" \
            CODE_SIGN_STYLE=Manual

      - name: Export IPA
        run: |
          xcodebuild -exportArchive \
            -archivePath DerivedData/MyApp.xcarchive \
            -exportOptionsPlist ExportOptions.plist \
            -exportPath DerivedData/Export

      - name: Upload to TestFlight
        env:
          APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
        run: |
          xcrun altool --upload-app \
            -f DerivedData/Export/MyApp.ipa \
            -t ios \
            --apiKey $APP_STORE_CONNECT_API_KEY

6. ステップ 4: パフォーマンスを最適化する

セルフホストランナーの最大の利点の 1 つは、永続的なキャッシュです。ここでは、Mac Mini M4 を最大限に活用するための主要な最適化を紹介します。

DerivedData のキャッシュを有効にする

ランナーが永続的であるため、DerivedData はビルド間で保持されます。一貫した DerivedData のパスを使用してください。

# In your workflow, always use:
-derivedDataPath DerivedData

# On the runner, periodically clean old DerivedData to save space:
# Add a cron job to clean builds older than 7 days
echo "0 3 * * 0 find ~/actions-runner/_work/*/DerivedData -maxdepth 0 -mtime +7 -exec rm -rf {} +" \
  | crontab -

SPM パッケージをキャッシュする

# Use clonedSourcePackagesDirPath to keep SPM packages on disk
xcodebuild build \
  -scheme "MyApp" \
  -clonedSourcePackagesDirPath ~/spm-cache \
  -derivedDataPath DerivedData

# This avoids re-downloading packages on every build

テストの並列実行

# Run tests in parallel across multiple simulators
xcodebuild test \
  -scheme "MyApp" \
  -destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2" \
  -destination "platform=iOS Simulator,name=iPhone 15,OS=17.5" \
  -parallel-testing-enabled YES \
  -maximum-parallel-testing-workers 4 \
  -derivedDataPath DerivedData \
  | xcbeautify

より見やすいログのために xcbeautify をインストールする

# xcbeautify formats Xcode output for CI environments
brew install xcbeautify

# Use it by piping xcodebuild output:
xcodebuild build -scheme "MyApp" | xcbeautify

7. よくある問題のトラブルシューティング

GitHub でランナーが「Offline」と表示される

これは通常、launchd サービスが実行されていないことを意味します。サービスの状態とログを確認してください。

# Check service status
sudo ./svc.sh status

# View logs
cat ~/actions-runner/_diag/Runner_*.log | tail -50

# Restart the service
sudo ./svc.sh stop
sudo ./svc.sh start

コード署名が「No signing certificate」で失敗する

launchd サービスは異なるユーザーコンテキストで実行されます。キーチェーンにアクセスできることを確認してください。

# Ensure the login keychain is unlocked for the runner user
security unlock-keychain -p "YOUR_PASSWORD" ~/Library/Keychains/login.keychain-db

# Or use a dedicated keychain in your workflow (recommended)
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain

シミュレーターの起動に失敗する

シミュレーターは時々動かなくなることがあります。ビルド間でリセットしてください。

# Shutdown all running simulators
xcrun simctl shutdown all

# Erase all simulator data (nuclear option)
xcrun simctl erase all

# Boot a specific simulator
xcrun simctl boot "iPhone 16 Pro"

ディスク容量が不足してくる

Xcode のビルドは大量のデータを生成します。自動クリーンアップを設定してください。

# Clean old DerivedData
rm -rf ~/Library/Developer/Xcode/DerivedData/*

# Remove old simulator runtimes
xcrun simctl runtime delete all

# Clean Homebrew cache
brew cleanup --prune=7

# Remove old Xcode archives
rm -rf ~/Library/Developer/Xcode/Archives/*

8. コスト分析

さまざまなチーム規模とビルド量に対する詳細なコスト比較を示します。

チーム規模 月間ビルド数 GitHub ホスト型の費用 MyRemoteMac の費用 月間節約額
個人開発者 100 ビルド(平均 10 分) 月額$80 月額$85 月額$5
小規模チーム(5 人) 500 ビルド(平均 10 分) 月額$400 月額$85 月額$325
中規模チーム(15 人) 1500 ビルド(平均 10 分) 月額$1,200 月額$229(M4 Pro) 月額$971
エンタープライズ(50 人以上) 5000 ビルド以上 月額$4,000以上 月額$458(M4 Pro 2 台) 月額$3,542以上

結論: 月に約 100 ビルドを超えるチームであれば、セルフホストの Mac Mini M4 はすぐに元が取れます。さらに、ウォームキャッシュを備えた永続的なハードウェアではビルドが速くなるため、チームの開発時間も節約できます。

関連ガイド

iOS ビルドを高速化する準備はできましたか?

専用 Mac Mini M4 を GitHub Actions ランナーとしてデプロイしましょう。月額$85から。

さらに詳しい情報をお探しですか?

ステップバイステップのセットアップ手順、設定リファレンス、トラブルシューティングについては、完全なドキュメントをご覧ください。

ドキュメントを開く →