2026 Macクラウドの常時バックグラウンドジョブ:Linux cronからmacOS launchdへの移行表と環境変数チェックリスト

MacクラウドへSSHできるのに、夜間同期やヘルスチェックをcrontabに載せると動かない・PATHが消える・ログがないことがあります。本稿はVPSと同様に運用したいチーム向けに、cronとlaunchdの意思決定表、LaunchAgentとLaunchDaemonの選定、最小plistlaunchctl bootstrap5段階の検証手順をまとめます。

リモートMacクラウドでlaunchdによりバックグラウンドジョブを管理する概念図

目次

1. 三つのつまずき:crontabは「合っていそう」なのにMacクラウドで壊れる理由

macOSにもcronは残りますが、統合スケジューラはlaunchdです。ヘッドレスMacクラウドでは「手動SSHは成功、定時だけ失敗」が典型化します。

  1. 環境変数とPATHの断絶:Linuxはcrontab内にPATH=を書けます。macOSのcronは環境が極小で、nodepython3が見つかりません。SSHは.zprofile.zshrcを読みますが、cron/launchdは既定で読みません。「手動で動く=定時も動く」と誤認しやすいです。
  2. 実行主体とキーチェーン:相対パス、~展開、キーチェーンアクセスはcronとLaunchAgentで挙動が異なります。GUI前提の処理を無頭環境へ載せると無言で失敗します。ビルドキューとディスクと重なると「DerivedData掃除が時だけ無ログ」になります。
  3. 観測性の弱さStandardOutPathStandardErrorPathが無いと、失敗がunified loggingの断片に散り、CIジョブと時系列で突き合わせづらくなります。Runbookが無いとcrontabを書き換えるループに陥ります。

次の表で「どのドメインのplistか」を一度決め、誤った層で粘らないようにします。

2. 意思決定表:cron、LaunchAgent、LaunchDaemon

ノートPCの「ログイン後に動けばよい」と違い、Macクラウドは多くが24時間稼働かつGUIセッション無しです。再起動後もlaunchdが確実に読み込む配置を優先します。

シナリオLinuxの習慣macOS推奨理由
開発機、ログイン後同期user crontab~/Library/LaunchAgentsユーザードメインでツールチェーンに届く
クラウド24/7、ログイン無しsystem cronLaunchDaemon または bootstrap済みAgentGUIと分離、再起動後も自動起動
rootや低番ポートroot crontabLaunchDaemon + UserName実行ユーザーを明示し監査可能に
秒級の高頻度systemd timerStartInterval + スロットル理解イベント結合に注意
一回限りのメンテatlaunchctl submit / RunAtLoad長期エントリを残さない
実務メモnvmpyenvに依存するならcronへの引き継ぎを期待しないProgramArguments絶対パスのシェルとスクリプトを書き、EnvironmentVariablesPATHを固定します。秘密はplist平文に置かず、キーチェーンやCIシークストアへ。

3. 実装手順:plist、launchctl、bootstrap、5段階検証

SSHで権限が取れている前提。ラベル命名はゼロトラストSSHのRunbookと揃えます。

  1. インタプリタを固定which bashwhich nodeを記録。Homebrewは/opt/homebrew/binまたは/usr/local/binの絶対パスで固定し、「対話シェルにはbrewがあるがジョブには無い」を潰します。
  2. 最小plistLabelProgramArgumentsStartCalendarInterval(またはStartInterval)、StandardOutPath/StandardErrorPathEnvironmentVariables。毎日03:15の例(パスは置換):
# 必須キー: Label / ProgramArguments / StartCalendarInterval または StartInterval / # EnvironmentVariables.PATH / StandardOutPath / StandardErrorPath # 例: 03:15 に /bin/bash -lc /usr/local/bin/run.sh # PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin、ログ nightly.log と .err # XML plist を ~/Library/LaunchAgents に置き launchctl bootstrap
  1. 配置と読み込み~/Library/LaunchAgentsまたは/Library/LaunchDaemonsへ配置しlaunchctl bootstrap …。変更時はbootout後にbootstrap、またはkickstart -k
  2. 試運転とログlaunchctl kickstart -kp gui/$(id -u)/com.example.vpsmac.nightly-sync。stdout/stderrのローテーションと、ファイル書き込み時のWorkingDirectoryを確認。
  3. 環境の突合:一時的にenv | sortをファイルへ(デバッグ後削除)、またはlaunchctl printで対話SSHと差分。
  4. CI/エージェントとの同居OpenClawxcodebuildのピークと重ねない。Niceや別ノードでI/O競合を下げる。

手順1〜4で実行、5〜6で観測と同居を担保。障害時はstdout/stderr末尾、launchctl print、plistハッシュを添付。

4. 引用・運用で使える数値と指針

① システムコマンドのみならPATH=/usr/bin:/bin:/usr/sbin:/sbinで足りることが多い。② カレンダー起動はタイムゾーンとDSTに従う。③ ログはnewsyslog等でローテしGB膨張を防ぐ。④ 短周期は結合されうる。⑤ plist 644 で改ざん困難に。

大きなrsyncxcodebuild依存解決が重なるとSSDが200〜400MB/s帯で飽和し、ネット障害に見えるI/O待ちが出る。10〜15分ずらすと再現率が下がることが多い。

5. 場当たりcrontabから、監査可能なMacクラウドへ

個人のexportと短命なcrontabは、環境のドリフトと秘密の散在、同居ワークロードの競合を招きます。plistをリポジトリ管理するのが本番ノードの礼儀です。

Linux VPSでmacOS前提を無理に再現するとlaunchd不在・キーチェーン齟齬・Xcode非整合が増え、コンテナでも署名/シミュレータまでは代替しにくい。2026年はVPSMAC M4 MacクラウドでlaunchdをRunbook化しplist方針を複製する方が単純です。

6. FAQ

crontabは使える?

可能ですがデフォルト推奨ではありません。PATH・絶対パス・ログ転送を必須にしてください。

LaunchAgentとLaunchDaemonの違いは?

AgentはユーザーのGUIセッション寄り、Daemonはシステムブート寄り。無頭ホストではキーチェーンとファイル所有者の要件で選びます。

plistを変えたのに反映されない

bootout/bootstrapの手順とLabelの一致、stderrパスの書き込み権限を確認してください。