SSH 経由でクラウド上の Mac に時間のかかるビルドを開始し、ノートパソコンを閉じてから再接続すると、ターミナルが消えていた――。このとき最も厄介なのは、単に実行し直すことではなく、タスクが失敗したのか、完了したのか、それともバックグラウンドで動き続けているのか判断できないことです。安定した運用に必要なのは、接続タイムアウトをむやみに延ばすことではありません。ネットワーク接続、ターミナルセッション、実際のタスクを3つの層に分けます。SSH はノードへの接続、tmux はターミナルの状態保持、ログと終了コードは実行結果の証明を担います。
まず切断の影響を受ける層を見極める
リモートデスクトップや SSH が切断されても、それはクライアントとクラウド Mac の間にある操作経路が途切れたことを意味するだけで、物理ノードが停止したわけではありません。ただし、SSH の疑似端末に直接ぶら下がっているフォアグラウンドプロセスは、セッション終了時にハングアップシグナルを受ける場合があります。GUI から開いたターミナルも、ウィンドウを閉じたりデスクトップからログアウトしたりするとライフサイクルが変わるため、無人タスクの実行基盤には適していません。
本番ビルドで試行錯誤する前に、まず10分間の小さなタスクで環境を確認します。
mkdir -p "$HOME/jobs/session-check"
cd "$HOME/jobs/session-check"
date -u +"start=%Y-%m-%dT%H:%M:%SZ" > run.log
sleep 600
date -u +"finish=%Y-%m-%dT%H:%M:%SZ" >> run.log
実行後に意図的に切断し、再接続して run.log を確認します。この基準テストにより、ノード自体が継続稼働しているかを確認できます。ただし、セッション管理の代わりにはなりません。
SSH のキープアライブが解決するのは「接続障害を検知するまでの時間」です。tmux が解決するのは「接続が切れた後も、復帰可能なターミナル上でタスクが維持されるか」です。両者を相互に代用することはできません。
SSH のキープアライブと明確なタイムアウトを設定する
ローカル Mac の ~/.ssh/config に、対象ノード専用の設定を追加します。アドレスとユーザー名は、管理コンソールに表示される実際の値へ置き換えてください。
Host minid-node
HostName <node-address>
User <system-user>
ServerAliveInterval 30
ServerAliveCountMax 3
TCPKeepAlive yes
ConnectTimeout 10
ServerAliveInterval 30 は、クライアントが30秒ごとにアプリケーション層の応答確認を送信する設定です。3回連続で応答がなければ、SSH は無効になった接続を終了し、ターミナルがいつまでも固まった状態になるのを防ぎます。ただし、自動再接続する機能ではなく、フォアグラウンドプロセスの継続も保証しません。
接続前に、最終的に適用される設定を確認できます。
ssh -G minid-node | grep -E 'serveralive|tcpkeepalive|connecttimeout'
ssh minid-node
ネットワークが頻繁に切り替わる環境では、タイムアウトを数十分まで延ばすことは推奨しません。接続が失われたことを早めに確定できれば、tmux に入り直して実際の進捗を確認しやすくなります。
長時間タスクを tmux で管理する
まず tmux が利用可能か確認し、存在しない場合に限って、現在の環境に合ったパッケージ管理方法でインストールします。
command -v tmux || brew install tmux
tmux new-session -s ios-build
セッション名には、ios-build、integration-test、asset-export のようにタスクの用途が分かる名前を付けます。意味の曖昧な work を長期間使い回すのは避けてください。セッションに入ったら専用ディレクトリを作成し、出力をターミナルとログの両方へ同時に記録します。
job_dir="$HOME/jobs/ios-build-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$job_dir"
cd "$job_dir"
set -o pipefail
caffeinate -i /path/to/run-build.sh 2>&1 | tee build.log
status=${PIPESTATUS[0]}
printf '%s
' "$status" > exit-code.txt
date -u +"%Y-%m-%dT%H:%M:%SZ" > finished-at.txt
Control-b を押してから d を押すと、タスクを終了せずにセッションからデタッチできます。ノードへ再接続した後は、次のコマンドを実行します。
tmux list-sessions
tmux attach-session -t ios-build
caffeinate -i は、コマンドの実行中に限ってアイドルスリープを避ける必要があることをシステムへ伝えます。特定のタスクに紐付けて使用し、手間を省くために常時実行しないでください。コマンドラインだけで完結するビルドでは、ディスプレイを強制的に起こしておく必要はありません。
重複実行を防ぐ
ネットワーク切断後は、まず tmux list-sessions と pgrep -fl run-build を実行します。以前のタスクが存在しないことを確認してから再起動してください。確認せずに実行すると、2つのビルドが同じ派生データディレクトリ、キャッシュ、成果物パスへ同時に書き込み、再現困難な混在結果が残る可能性があります。
ログと終了コードを検収基準にする
「再接続後もターミナルの出力が流れている」だけでは、正常性を確認したことにはなりません。長時間タスクでは、少なくとも開始時刻、終了時刻、完全なログ、終了コードを毎回残す必要があります。終了コードが 0 の場合にのみ、スクリプトが取り決めどおり正常終了したと判断できます。ログ末尾に特定の単語が表示されていても、終了コードの代わりにはなりません。
次の順序で確認すると、状態をすばやく判断できます。
| 確認項目 | コマンド | 判断 |
|---|---|---|
| セッションが存在するか | tmux list-sessions |
存在していても、タスクが実行中とは限らない |
| プロセスが存在するか | pgrep -fl run-build |
現在の実行インスタンスを確認する |
| ログが増えているか | tail -n 30 build.log |
進捗または停止箇所を判断する |
| 正常終了したか | cat exit-code.txt |
0 はスクリプトの成功を示す |
| 終了時刻 | cat finished-at.txt |
結果が今回の実行に対応するか判断する |
スクリプトでは実行のたびに新しいディレクトリを作成し、前回のログを上書きしないようにします。クリーンアップが必要な場合は、アーカイブ済みであることを確認したディレクトリを日付単位で削除してください。~/jobs 全体に対して再帰削除を実行してはいけません。
本番運用前に意図的な切断テストを行う
本番利用を始める前に、安全に繰り返せるテストタスクを起動し、SSH の切断、リモートデスクトップの終了、ローカルネットワークの切り替えを順番に検証します。再接続するたびに、tmux セッション、対象プロセス、ログの増加、終了コードファイルを確認してください。
タスクが GUI に依存する場合は、リモートデスクトップを切断した後も処理が継続するかを別途検証する必要があります。コマンドラインツールと GUI アプリケーションでは、ライフサイクルが異なります。タスクが予定より早く終了した場合は、まずスクリプトの終了コードとログを確認し、次にターミナルが閉じられていないかを調べ、最後にストレージ容量とプロセスリソースを確認します。すべての失敗をネットワークの問題と決めつけないでください。
運用開始に必要なチェックリストには、次の項目を含めます。
- SSH 設定を
ssh -Gで検証できること。 - 長時間タスクの種類ごとに独立した tmux セッションを使用すること。
- タスクディレクトリを時刻ごとに作成し、以前の結果を上書きしないこと。
- 標準出力と標準エラー出力を、検索可能な同一ログへ記録すること。
- 終了コードと UTC の終了時刻を個別に保存すること。
- 切断後は最初に既存の状態を復元し、タスクを重複起動しないこと。
- 完了後は不要なセッションを明示的に終了し、成果物をアーカイブすること。
よくある質問
SSHが切断されるとリモートMac上の処理も必ず停止しますか?
必ず停止するわけではありません。SSH端末へ直接ぶら下がるプロセスは終了する可能性がありますが、tmux内で起動した処理は継続します。再接続後にセッションとログを確認します。
ServerAliveIntervalだけで長時間タスクを保護できますか?
できません。この設定は応答しない接続を検出するもので、プロセスを保持する機能ではありません。tmuxを使い、標準出力、エラー、終了コードをファイルへ保存してください。
MiniD クラウド Mac
専用物理 Mac mini を日・週・月単位でレンタル
各プランは専用の物理 Mac mini で稼働し、リモートデスクトップと SSH の両方で接続できます。最新の機種・リージョン・期間は注文ページでご確認ください。