Kanade Electronicskanaelecom
clawd

Claude Code を systemd で常駐させる

再起動しても動き続けよう

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@0claude@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 がやっているのは:

  1. ~/.local/bin/claudetmuxcurl の存在確認
  2. [email protected]~/.config/systemd/user/ にコピー
  3. systemctl --user daemon-reload
  4. systemctl --user enable --now [email protected]

--now を付けているので、enable (自動起動登録) と start を一度に済ませます。

インスタンスの起こし方

cmd
systemctl --user start claude@00 番のインスタンスを起動
systemctl --user start claude@11 番を追加で起動
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 -fsystemd 側のログを追う

@ 以降は単なる ID なので、用途別に claude@devclaude@blog のように名前付きで使うこともできます (%i がそのまま文字列として展開される)。

セッションに入る

サービス本体は tmux の中で動いているので、tmux attach で覗きにいきます。

cmd
tmux lsセッション一覧 (claude:0 等)
tmux attach -t claude:00 番のセッションに入る
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-control URL があれば、別マシンからブラウザで状態を見つつ指示を投げられる
  • クラッシュ時の自動復旧は付いていない: ユニットには Restart= が入っていないので、落ちたらこちらで restart する設計。長時間放牧したい場合は自分で Restart=on-failureRestartSec を足すと吉