Claude Code を使っていて、ドライバなど低レイヤで再起動を伴う開発だといちいち中断されてめんどうです。 systemd を使えば再起動しても自動的にセッションを継続できます。
インストール
実装
[email protected] という systemd のサービスを定義しています。
[Unit]
Description=Claude Code (%i)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=%h
Environment=TERM=xterm-256color
ExecStartPre=-/usr/bin/tmux kill-session -t claude:%i
ExecStart=/usr/bin/tmux new-session -d -s claude:%i '%h/.local/bin/claude -c --remote-control claude:%i@%H --dangerously-skip-permissions "system has rebooted. continue tasks."'
ExecStop=-/usr/bin/tmux kill-session -t claude:%i
[Install]
WantedBy=default.target
ポイント:
- テンプレート (
@):claude@0、claude@1のように%iを変えるだけで並列に起こせる Type=oneshot+RemainAfterExit=yes:tmux new-session -dがすぐ抜けても systemd 側はサービスを「起動中」のままにするExecStartPre=-の-: 既存セッションがなければ失敗を無視%h/%H: home ディレクトリと hostname。Remote Control の URL に hostname を載せている--user単位: root 不要、~/.config/systemd/user/で完結
インストール
ワンライナーでユニットを配置して claude@0 を起こすところまで。
curl -fsSL https://raw.githubusercontent.com/kanade-k-1228/claude.service/main/install.sh | bash
install.sh がやっているのは:
~/.local/bin/claudeとtmux、curlの存在確認[email protected]を~/.config/systemd/user/にコピーsystemctl --user daemon-reloadsystemctl --user enable --now [email protected]
--now を付けているので、enable (自動起動登録) と start を一度に済ませます。
インスタンスの起こし方
| cmd | |
|---|---|
systemctl --user start claude@0 | 0 番のインスタンスを起動 |
systemctl --user start claude@1 | 1 番を追加で起動 |
systemctl --user stop claude@0 | 停止 |
systemctl --user restart claude@0 | 再起動 |
systemctl --user status claude@0 | 状態確認 |
systemctl --user enable claude@0 | 起動時の自動起動を登録 |
systemctl --user disable claude@0 | 自動起動を解除 |
systemctl --user list-units 'claude@*' | 動いているインスタンスの一覧 |
journalctl --user -u claude@0 -f | systemd 側のログを追う |
@ 以降は単なる ID なので、用途別に claude@dev、claude@blog のように名前付きで使うこともできます (%i がそのまま文字列として展開される)。
セッションに入る
サービス本体は tmux の中で動いているので、tmux attach で覗きにいきます。
| cmd | |
|---|---|
tmux ls | セッション一覧 (claude:0 等) |
tmux attach -t claude:0 | 0 番のセッションに入る |
Ctrl-b d | 離脱 (Claude は走り続ける) |
tmux kill-session -t claude:0 | 強制終了 (systemd 側は失敗扱い) |
- 離脱は必ず
Ctrl-b d: ウィンドウを閉じても tmux セッションは残るが、Ctrl-cで Claude を殺すとサービスは死にます。ExecStartPreで次回起動時にクリーンアップされるので、再startすれば復活します。 - Remote Control URL はセッション内に表示:
--remote-control claude:%i@%Hで起動しているので、Claude が吐き出す URL を別マシンから開けばリモート操作が可能。
ログアウト後も生かす
--user セッションはデフォルトでログアウト時に終了します。SSH で繋いだまま放置したい場合は linger を有効に。
sudo loginctl enable-linger $USER
これで、ログアウト後もユーザの systemd インスタンスが残り続けます。サーバ用途で常駐させるなら必須。
lingerはユーザ単位: 設定したユーザだけが対象。サーバを共有しているなら他のユーザに影響なし。loginctl user-status $USERで linger 状態を確認できます。
アンインストール
これもワンライナー:
curl -fsSL https://raw.githubusercontent.com/kanade-k-1228/claude.service/main/uninstall.sh | bash
中身は走っているインスタンスを stop + disable してから、ユニットファイルを消して daemon-reload するだけ。
どういう時に使うか
- 複数エージェントを放牧したい: tmux + worktree でも回せますが、再起動跨ぎ・ログイン跨ぎが欲しいなら systemd に乗せた方が楽
- 遠隔から見守りたい:
--remote-controlURL があれば、別マシンからブラウザで状態を見つつ指示を投げられる - クラッシュ時の自動復旧は付いていない: ユニットには
Restart=が入っていないので、落ちたらこちらでrestartする設計。長時間放牧したい場合は自分でRestart=on-failureとRestartSecを足すと吉