金曜日の午後、リリース担当のチームメンバーがチャットで一言聞いてきた。「うちの月額契約の Mac mini、来週水曜で契約終了なんだけど、中の証明書やシミュレータのデータ、Homebrew のキャッシュってどうする?」誰もすぐには完全なリストを答えられなかった――これはまさに移行失敗の典型的な前兆だ。クラウド Mac mini は使い勝手が良い一方、多くの状態は「使っているうちにどこにあるか忘れてしまう」もので、いざ終了日になって初めて十数個のディレクトリに散らばっていることに気づく。
なぜ契約終了前の移行はよく失敗するのか
多くの人の「移行」に対する理解は「プロジェクトフォルダをローカルにコピーする」で止まっているが、実際にビルドを詰まらせるのは大抵隠れた設定だ。~/.ssh に発行済みのデプロイキー、Keychain 内のディストリビューション証明書、~/Library/Developer/Xcode/DerivedData の増分ビルドインデックス、そして各種ツールがユーザーディレクトリ配下にひっそり書き込むキャッシュパス。これらは普段は目立たないが、マシンが期限切れで解放されてしまえば二度と取り戻せない。
移行とは「ファイルをバックアップする」ことではなく、「即座に動くマシンを再現する」ことだ。判断基準は「ファイルをコピーし終えたか」ではなく、「新しいマシンで一度ビルドを走らせて、旧マシンと同じ成果物が出るか」である。
移行前の資産リスト:何を持ち出す必要があるか
まず持ち出すべきものを二つに分類する。分類そのものが漏れを減らしてくれる。
開発環境の設定
シェル設定(.zshrc/.zprofile)、SSH 鍵と known_hosts、Git のグローバル設定と認証情報、Xcode の署名証明書とプロビジョニングプロファイル、そして security コマンドでエクスポートした Keychain エントリが含まれる。これらのファイルは容量は小さいが一つも欠かせないため、単独で一つのアーカイブにまとめることを推奨する。
プロジェクトと依存関係のキャッシュ
コードリポジトリ(理論上はすべてリモートにあるはずだが、ローカルで未 push のブランチは別途確認が必要)、CocoaPods と SwiftPM のローカルキャッシュ、Homebrew でインストールしたパッケージ一覧(brew bundle dump で Brewfile を書き出すほうが /opt/homebrew 全体をコピーするより圧倒的に効率が良い)、そして Podfile.lock、.xcode-version といったロックファイルが含まれる。
三層バックアップ戦略:rsync 増分 + tar アーカイブ + スナップショットダウンロード
一つの手段で全シナリオをカバーできると期待してはいけない。三層を組み合わせて初めて安定する。
| 層 | ツール | 適用シーン | 欠点 |
|---|---|---|---|
| 第一層 | rsync 増分同期 | 日常の継続的バックアップ、プロジェクトファイル・設定ファイル | 転送先が書き込み可能である必要があり、超大型バイナリには不向き |
| 第二層 | tar によるパッケージアーカイブ | Keychain や証明書など機密性の高い小容量データの一括パッケージ化 | 増分更新には不向き |
| 第三層 | プラットフォームのスナップショットダウンロード | 前二層が失敗した場合の最後の保険 | 容量が大きく、出口帯域の制限を受け、時間がかかる |
rsync で増分同期する
ローカルから起点として、Mac mini 上の主要ディレクトリを自機や オブジェクトストレージのマウントポイントへ同期する。
rsync -avz --delete \
--exclude 'DerivedData' \
--exclude 'node_modules' \
dev@hk1.oncemini.com:~/projects/ \
~/backup/mac-mini-hk1/projects/
DerivedData や node_modules など再生成可能なディレクトリを除外するだけで、同期時間を数十分から数分に短縮できる。契約終了の一週間前から毎日一回実行を始めることを推奨する。最終日になって初めて同期を始めるのは避けたい――初回のフル同期にかかる時間は往々にして過小評価されがちだ。
不変アーカイブをパッケージ化する
証明書や鍵といった頻繁には変化しないが絶対に失えないデータは、単独でパッケージ化して暗号化する。
tar czf keychain-backup.tar.gz \
~/Library/Keychains \
~/.ssh
gpg -c keychain-backup.tar.gz
暗号化したアーカイブは、その後 rsync で転送するか直接ダウンロードすることで、平文の鍵が転送経路上に残るのを避けられる。
プラットフォームのスナップショットダウンロードを最後の保険にする
前二層がネットワークの問題で完了しなかった場合、コンソール上のマシン全体のスナップショットダウンロードを最後の保険として使える。ただし事前に容量を計算しておくこと――512GB のシステムディスクを住宅用回線でダウンロードすると数時間かかる場合があるため、必ずバッファ時間を確保し、契約終了の数時間前になって初めて実行を始めるようなことは避けるべきだ。
よくある落とし穴とチェックリスト
brew bundle dumpで Brewfile を書き出し忘れ、新しいマシンでのソフトウェア導入がすべて記憶頼りになり、バージョン番号が食い違う。- プロジェクトのコードだけをバックアップし、
.env内のローカル環境変数をバックアップし忘れ、新マシンでのビルド時に設定不足でエラーになる。 - 一般ユーザー権限で rsync を実行し、システムレベルの証明書ファイルの読み取り権限が漏れてしまい、アーカイブが不完全なのにエラーも出ない。
- 契約終了の数時間前になって初めてスナップショットのダウンロードを始め、帯域の変動に遭遇して間に合わなくなる。
- 移行後に旧マシン上の鍵やトークンを削除しておらず、解約後もこれらの認証情報が理論上は有効なままになり、セキュリティリスクとなる。最後のログイン時に自ら失効させるべきだ。
移行後の新マシンでのコールドスタート検証
引っ越しが完了したことは終わりを意味しない。新しい環境で一度完全な検証を走らせて初めて締めくくれる。
brew bundle install --file=Brewfile
pod install --repo-update
xcodebuild -workspace App.xcworkspace \
-scheme App -configuration Release \
clean build
shasum -a 256 build/App.app/App
新旧二回のビルドの shasum 出力を比較し、一致してこそ移行が本当に完了したと言える。この一手はよく省略されるが、まさに「環境に何も失われていない」ことを証明できる唯一の客観的な証拠であり、「見た感じ動く」よりはるかに信頼できる。
よくある質問
契約終了後、データはどれくらい保持されますか?
標準の保持期間は72時間です。締め切り直前に慌てないよう、期限の48時間前までにバックアップを完了させることを推奨します。
rsync とプラットフォームのスナップショットダウンロードはどちらを使うべきですか?
まず rsync でローカルまたはオブジェクトストレージへ差分バックアップするのが速く再開可能です。スナップショットダウンロードは容量が大きく出力帯域の制約を受けるため、最後の保険として使います。
移行後に新環境が完全であることをどう確認しますか?
同じ Brewfile、Podfile.lock、.xcode-version で新マシン上に環境を再構築し、フルビルドを実行して生成物のハッシュを比較します。ハッシュが一致すれば移行成功です。
専用のMac miniでビルドフローをスムーズに回したいですか?
コンソールでMac miniをレンタルする