接続してから移行

クラウドMacに3分で接続

SSHでコマンドを実行し、VNCでmacOSの画面を操作できます。仮想マシンではなく、専有の物理マシンです。ソースコード、ツールチェーン、CIを段階的に移行し、ローカル環境の問題まで持ち込まないようにしましょう。

接続情報とSSH公開鍵がそろっていれば、以下の手順で接続できます。初回のツールチェーン設定にかかる時間は、接続手順に含まれません。

まずSSHで接続。以降の操作はこの経路で

ローカルのターミナル、SSH公開鍵、コンソールに表示されたホスト情報を用意します。例にある HOST、PORT、USER は、提供されたホストアドレス、SSHポート、ユーザー名にそれぞれ置き換えてください。例の値をそのまま使わないでください。

01 · ローカルで準備

公開鍵を登録し、秘密鍵は送らない

専用の鍵があれば、そのまま使えます。ない場合は、お使いのPCでEd25519鍵ペアを生成し、パスフレーズを設定してから、 .pub ファイルの内容をコンソールのSSH公開鍵設定に追加します。

ssh-keygen -t ed25519 \
  -f ~/.ssh/osxbuild_ed25519

cat ~/.ssh/osxbuild_ed25519.pub

秘密鍵はローカルに保管してください。チケット、メール、コードリポジトリには貼り付けないでください。アップロード後、コンソールの案内に従って公開鍵が対象インスタンスに適用されたことを確認します。

02 · 接続を確認

提供されたポートで直接接続

接続情報はコンソールのインスタンス詳細で確認できます。初回のホストフィンガープリント確認では、照合可能な提供情報と突き合わせてください。確認できない場合はチケットを送信し、ホスト検証を無効にして警告を回避しないでください。

ssh -i ~/.ssh/osxbuild_ed25519 \
  -p PORT USER@HOST

sw_vers
uname -m
xcodebuild -version

まずOS、アーキテクチャ、Xcodeのバージョンを確認します。最後のコマンドでツールチェーンが未設定と表示された場合は、インストールとパスの選択を済ませてからビルドタスクを設定してください。

03 · 接続先を固定

接続先にローカル名を設定

以下の内容をローカルの ~/.ssh/configに記述します。エイリアスの例は bakeです。以降の同期、トンネル、トラブルシューティングではこの名前を使えるため、毎回アドレスやポートを入力する手間を省けます。

Host bake
  HostName HOST
  Port SSH_PORT
  User SSH_USER
  IdentityFile ~/.ssh/osxbuild_ed25519
  IdentitiesOnly yes
  ServerAliveInterval 30
  ServerAliveCountMax 3

保存したら、次のコマンドを実行します。 ssh bakeKeepAlive設定は接続の切断を検知するためのものです。ネットワークの再接続を行う機能ではなく、ターミナルのタスクを自動で再開することもありません。

GUIデスクトップにはVNCを使用し、SSHトンネル経由で接続

Xcodeの設定、キーチェーンの確認、シミュレーターの操作が必要な場合は、デスクトップに接続します。まず、コンソールに記載されたVNC接続情報を確認してください。デフォルトのポート番号をすべてのマシンに共通する接続情報として使わないでください。

使い慣れたクライアントを選ぶ

macOSでは標準の「画面共有」を使用できます。WindowsやLinuxでは、VNC対応のTigerVNCクライアントを利用できます。クライアントを別途インストールする場合は、公式配布元から入手し、提供されたサービスの認証方式に対応していることを確認してください。

まず通信量を抑え、次に画質を調整

まずは 1440 × 900 または 1600 × 1000 のデスクトップサイズから始めましょう。高解像度ディスプレイの画面全体に広げる必要はありません。選択できる場合は、まず24ビットカラーを試し、ネットワークに制約がある場合は16ビットに切り替えます。選択肢はクライアントとサーバーの対応状況によって異なります。

ターミナルでのアーカイブ作成とリモートデスクトップは、別々の操作方法です。画面の動きが遅い場合も、SSHでビルドを続け、ログやIPAを取得できます。画面更新にパイプライン全体を依存させる必要はありません。

デスクトップのポートだけをローカルに転送

ローカルで以下のコマンドを実行し、このターミナルを開いたままにします。VNC_PORT を、提供されたサーバーポートに置き換えてください。例の 15900 はローカルポートです。未使用のポートに変更できます。

ssh -N \
  -L 127.0.0.1:15900:127.0.0.1:VNC_PORT \
  -o ExitOnForwardFailure=yes \
  bake

続いて、VNCクライアントのアドレス欄に 127.0.0.1、ポート欄に 15900を入力します。アドレス欄が1つのクライアントでは、ドキュメントに記載された形式で入力してください。

VNCの認証には、引き続き提供されたデスクトップ認証情報を使います。SSH鍵でデスクトップのパスワードを代用することはできません。接続を終えたらクライアントを終了し、 Ctrl + C を押してトンネルを閉じます。

デスクトップに接続できない場合は、接続経路を順に確認
症状 まず確認すること 次の手順
ローカルポートを開けない SSH接続の状態と、ローカルポートの使用状況 別のローカルポートに変更し、トンネル用ターミナルに表示されたエラーを残す
トンネルは確立したが、デスクトップ接続が拒否される 提供されたVNCポートと、サービスの待ち受け状態 インスタンス詳細を確認し、デスクトップ用ポートをインターネットに公開しない
認証後に接続できない デスクトップのユーザー名・パスワードと、クライアントの認証方式への対応 提供された認証情報を再確認する。SSH秘密鍵をVNCパスワードとして使わない
ログインできるが、画面の更新が遅い 解像度、色深度、ローカルネットワーク、ノードまでの距離 画面の転送量を減らし、GUIが不要なビルドはSSHで続行する

移行は3段階。ディスク全体をそのままコピーしない

まずデータをそろえ、次にツールチェーンを合わせ、最後にCIを接続します。各段階で確認結果を残し、クリーンなアーカイブを一度作成してからキャッシュと自動化を戻しましょう。

第1段階 · データ

ソースコードを同期し、一時生成物は作り直す

Gitでプロジェクトを取得するか、rsyncでローカルの作業ディレクトリやリポジトリ外のリソースを同期します。初回はDerivedDataや古いbuildディレクトリを含めず、署名用秘密鍵も通常のファイル同期に混ぜないでください。

rsync -az --progress \
  --exclude='DerivedData/' \
  --exclude='build/' \
  --exclude='*.p12' \
  --exclude='*.mobileprovision' \
  ./ bake:~/project/

確認項目:同期先ディレクトリ、コミットのバージョン、必要なリソースが一致していること。例には削除オプションを含めていないため、初回同期でリモートのファイルを誤って削除しません。同期の成功をバックアップ完了とみなさないでください。

第2段階 · ツールチェーン

バージョンを合わせてから依存関係を復元

プロジェクトに応じてXcodeをインストールまたは選択し、Homebrewを設定します。CocoaPodsはロックファイルから復元し、SPMは依存関係を再解決します。キャッシュはツールチェーンと依存関係のバージョンが一致するものに限り、出所が不明なディレクトリは再利用しないでください。

xcode-select -p
xcodebuild -version
brew --version

bundle install
bundle exec pod install

確認項目:バージョンがローカル環境の基準と一致し、依存関係を解決できること。最後の2つのコマンドはCocoaPodsを使うプロジェクトでのみ実行します。署名証明書は管理された経路から別途キーチェーンに取り込み、有効期限とプロビジョニングプロファイルの対応を確認してください。

第3段階 · CI接続

ランナーを登録し、最後に配布を設定

GitHub ActionsまたはGitLab Runnerに専用ランナーを登録します。まずバージョンを確認し、次にプロジェクトのFastlaneレーンを実行します。アーカイブとエクスポートを検証してから、アップロード手順を追加してください。

xcodebuild -list \
  -workspace App.xcworkspace

bundle exec fastlane ios build

確認項目:ログからコミットのバージョン、Scheme、成果物のパスを追跡できること。例のワークスペース名とレーン名は、プロジェクトに合わせて変更してください。リリース用の認証情報は個別に権限を付与し、ソースコードと一緒に配布しないでください。

CIを接続する際は、ジョブの実行先をこのマシンに指定

セルフホストランナーは、利用中の物理ノードで動作します。ラベルはジョブの振り分けに、認証情報はアクセス許可に使い、両者を混同しないでください。まず1つのジョブを動かし、並列数やディスク使用量はその後に検討します。

GitHub Actions:専用ラベルでビルドマシンを指定

リポジトリまたは組織の設定にある手順に従ってself-hosted runnerを登録し、カスタムラベル osxbuildを追加します。以下のワークフローはツールチェーンを確認してアーカイブを作成します。署名用情報の注入、IPAのエクスポート、配布は行いません。

name: iOS archive
on:
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ios-${{ github.ref }}
  cancel-in-progress: false

jobs:
  archive:
    runs-on: [self-hosted, macOS, ARM64, osxbuild]
    steps:
      - uses: actions/checkout@v4
      - name: Check Xcode
        run: xcodebuild -version
      - name: Archive
        run: |
          xcodebuild \
            -workspace App.xcworkspace \
            -scheme App \
            -configuration Release \
            -archivePath "$RUNNER_TEMP/App.xcarchive" \
            archive

ワークスペースとSchemeを実際の設定に置き換え、Schemeが共有されていることを確認してください。署名用情報を保持するランナーは、信頼できるリポジトリとジョブでのみ使用します。ブランチごとに異なる並行グループが作られますが、ビルドディレクトリの競合には引き続き注意が必要です。

Jenkins:SSH経由で専用エージェントを起動

Jenkinsに固定ノードを追加し、専用のビルドディレクトリをリモート作業ディレクトリに指定します。ラベルは osxbuild-macに設定します。SSH経由でエージェントを起動する方法を選び、提供されたホストとポートを入力してください。秘密鍵はJenkinsの認証情報ストアで管理します。

pipeline {
  agent { label 'osxbuild-mac' }

  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }
    stage('Toolchain') {
      steps {
        sh 'xcodebuild -version'
      }
    }
    stage('Build') {
      steps {
        sh 'bundle exec fastlane ios build'
      }
    }
  }
}

エージェントに必要なJavaが利用可能であること、SSH認証情報が有効であること、ホストフィンガープリントが検証済みであることを確認します。SSHで起動した非対話環境では、ローカルのシェル設定が読み込まれない場合があります。Homebrew、Ruby、Fastlaneのパスを明示的に設定してください。

GitLab Runnerも同じ手順で接続します。ランナーを登録し、信頼できるプロジェクトに限定して、プロジェクトラベルを設定してから、バージョン確認ジョブで環境を検証してください。GUIセッションが必要なテストは、まず実行条件を個別に確認します。

まずは実行スロットを1つだけ使います。並列数を増やす前に、メモリのピーク使用量、シミュレーターの数、DerivedDataのパスを確認してください。複数のジョブが同じアーカイブディレクトリに同時に書き込まないようにします。

6拠点から、操作する人に合わせて選ぶ

GUIデスクトップを頻繁に使う場合は、チームからノードまでの接続経路を優先して比較します。CIが中心なら、ソースコード、依存関係、成果物のアップロード経路を確認しましょう。地理的な距離は目安の一つで、実際の使い勝手は通信事業者、ルーティング、ローカルネットワークにも左右されます。

シンガポール

SG · UTC+8

東南アジアとの協業に適したタイムゾーンです。日中にXcodeをリモート操作することが多いチームは、まず現地からの接続状況を比較してください。

シンガポールを選択

東京

JP · UTC+9

東アジアとの協業に適したタイムゾーンです。日中のインタラクティブな開発と夜間のアーカイブ作成を同じマシンで行い、環境の引き継ぎを減らせます。

東京を選択

ソウル

KR · UTC+9

北東アジアとの協業に適したタイムゾーンです。リモートデスクトップをよく使う場合は、画面の更新速度と入力への反応を比較してから、チームの接続先を決めましょう。

ソウルを選択

香港

HK · UTC+8

中国南部や東南アジアとの協業に適したタイムゾーンです。リモート操作だけでなく、依存関係のダウンロードや成果物のアップロードも確認し、一度接続できたことだけで判断しないようにしましょう。

香港を選択

米国東部

US-E · UTC−5 / −4

北米東部や西ヨーロッパとの協業に適しています。夜間ビルドのスケジュールには明示的なタイムゾーンを設定し、夏時間による現地時刻の変化に注意してください。

米国東部を選択

米国西部

US-W · UTC−8 / −7

北米西海岸との協業に適しています。ビルド時間を現地の勤務日に合わせやすく、時差をまたぐ引き継ぎでは、ログに明確な時刻を残せます。

米国西部を選択

2つの構成タイプから、上記6拠点を選べます。実際の提供状況はコンソールの最新情報をご確認ください。ノードは365日稼働します。ローカルネットワークの切断やSSHセッションの切断は、マシンの稼働状態とは分けて判断してください。

接続できたら、入口と署名情報を適切に管理

まず、接続できることを確認済みの経路を1つ残してからアクセス設定を変更します。変更は一度に1つずつ行い、新しい接続を確認してから古いセッションを閉じてください。マシンに接続できなくなる事態を防げます。

  1. 01

    鍵で接続できることを確認してから、パスワード認証を無効化

    まず別のターミナルを開き、専用鍵でログインできることを確認してから、システムのSSH設定でパスワード認証を無効にします。変更前に設定ファイルの構文と、接続を復旧する方法を確認してください。システム設定に不慣れな場合は、操作前にチケットで確認しましょう。

  2. 02

    必要なポートだけを開放

    用途に応じてリモートログインやサービスへの入口を絞り、VNCはSSHトンネル経由で使いましょう。デバッグサービス、ビルド制御用インターフェース、一時的なファイルサービスをインターネットに直接公開しないでください。ローカルアドレスへのバインドとアクセス制御を併せて確認します。

  3. 03

    人と用途ごとに鍵を分ける

    手動ログインとCIには別々の鍵を使います。担当者の変更時や認証情報の漏えいが疑われる場合は、古い権限をすぐに取り消してください。鍵をローテーションするときは、新しい公開鍵を追加して接続を確認した後、古い公開鍵を削除します。最後にランナーとチームの引き継ぎ記録を更新してください。

  4. 04

    署名用情報を通常のログに残さない

    ビルドに必要な間だけキーチェーンのロックを解除し、使用後はアクセスを制限します。API Key、証明書のパスフレーズ、matchの復号用認証情報は認証情報システムから注入してください。スクリプトが機密変数を出力しないことを確認し、秘密鍵ファイルをリポジトリに保存しないでください。

  5. 05

    利用期限前に成果物と設定を取り出す

    保持が必要なソースコード、IPA、アーカイブ、パイプライン設定はチーム管理のストレージに同期し、ファイルを開けることを確認してください。契約期間終了後はディスクの消去とシステムの再インストールが行われるため、マシンのローカルディレクトリだけを唯一の保存先にしないでください。

問い合わせには、引き継ぎ情報をご用意ください。チケットには注文番号、ノード、エラー発生日時とタイムゾーン、機密情報を伏せたログ末尾50行を添付してください。秘密鍵、証明書のパスフレーズ、アカウントのパスワードは送らないでください。接続に関する問題は、コンソールのチケットまたは support@osxbuild.com までお問い合わせください。

接続経路を整えて、次のアーカイブ作成へ

マシンをお持ちの場合は、まずコンソールの提供情報をご確認ください。構成を選ぶ段階であれば、2種類の専有クラウドMacからビルド量に合わせて選び、チームの所在地に応じて拠点を決めましょう。