Claude Codeの自己ホストランナー、SIGTERM後も猶予時間を持てるように──defer-shutdown-max-minの仕組み
anthropics/claude-codeのv2.1.238で、`claude self-hosted-runner`コマンドに`--defer-shutdown-max-min`オプションが追加されました。ランナーがSIGTERMを受け取っても、既存の接続セッションへのサービス提供を指定分数だけ継続し、その後にparkして終了する仕組みです。同じリリースには、認証ヘッダーを毎接続ごとに要求するegressプロキシ向けの認証オプションも追加されています。

目次
2026年8月27日、GitHubの公式リリースノート(anthropics/claude-code)を実際に開いて確認した内容です。 v2.1.238(2026年8月20日公開)の変更点一覧に、次の記載があります(原文と訳)。
"Added
claude self-hosted-runner --defer-shutdown-max-min <minutes>: on SIGTERM, keep serving attached sessions, park what is left after that many minutes, then exit"(訳:
claude self-hosted-runner --defer-shutdown-max-min <分>を追加。SIGTERMを受け取ると、アタッチされたセッションへのサービス提供を継続し、指定した分数が経過した時点で残っているものをparkし、その後終了する)
3行まとめ
claude self-hosted-runner(自己ホスト型のClaude Codeランナー)に、--defer-shutdown-max-min <分>オプションが追加された- SIGTERM(一般的な終了シグナル)を受け取っても即座に停止せず、既存のアタッチ済みセッションへのサービス提供を指定した分数だけ継続し、その後に残っているセッションをparkしてから終了する
- 同じリリースには、egressプロキシ向けの
--proxy-authorization-command・--proxy-authorization-fileオプションも追加されている
公式ドキュメントで確かめた3点
- デフォルト値は
0で、これは機能自体が無効という意味。明示的に分数を指定しない限り、ランナーは従来通りSIGTERMを受け取った瞬間からドレイン(セッションの退避)を始める- CHANGELOGにあった「park」という言葉は、公式ドキュメントでは「release(解放)」と表現されている。解放されたセッションは、そのユーザーが次にメッセージを送った時点で、別の空いているランナー上で自然に再開される——というのが実態だ
--defer-shutdown-max-minを設定する際は、ホスト側の停止タイムアウトを「設定した分数+155秒(デフォルト設定の場合)」以上に引き上げる必要がある、と公式ドキュメントが明記している。これを怠ると、ランナーが処理を終える前にホストに強制終了され、保持していたセッションがpost-sessionフックを実行されないまま終わる
「即座に落ちない」ことの意味
自己ホスト型のランナー(企業が自社インフラ上でClaude Codeのセッションを実行するための常駐プロセス)は、デプロイの更新やインフラのスケーリングの際に、SIGTERMシグナルで停止を指示されることがあります。従来の挙動がどうだったかについて、今回確認したリリースノートには明記がありませんが、「on SIGTERM, keep serving attached sessions(SIGTERMを受け取ってもアタッチされたセッションへのサービス提供を続ける)」という記載から、少なくともこのオプションを使わない場合は即座に停止していた可能性がうかがえます。
--defer-shutdown-max-minを指定すると、SIGTERMを受け取った時点で稼働中のセッションを強制切断せず、指定した分数のあいだは通常通りサービスを提供し続けます。その猶予時間が経過した時点で、まだ残っているセッションは「park(一時停止・退避)」され、その後にプロセス自体が終了する、という段階的な停止手順です。
これは、長時間実行中のエージェントタスクがある状態でインフラのローリングアップデートを行う際に、タスクを強制的に中断させず、猶予時間内に自然な区切りで終わらせる、あるいは別のランナーに引き継がせる、といった運用を意図した機能だと考えられます。
公式ドキュメントで判明した3段階のタイムライン
公式ドキュメント「Deploy self-hosted environments to production」の「Defer the drain past the first signal(最初のシグナルの先までドレインを遅らせる)」という節に、SIGTERM受信後の詳しい挙動が説明されていた。最初のシグナルを受け取ってから、ランナーは次の3段階を通る。
| 段階 | タイミング | 挙動 |
|---|---|---|
| ① 通常提供 | 最初のn分間 | セッションを通常通り提供し続ける。--release-idle-session-minを設定していれば、その時間アイドルなセッションは早めに解放される |
| ② 全解放 | n分が経過した時点 | 保持している全セッションを、アイドルかどうかに関わらず解放する。ターン処理中のセッションはターンの終了を、バックグラウンドタスクがあれば最大60秒待ってから解放する |
| ③ ドレイン | 解放後の猶予(デフォルト75秒)が尽きた時点 | まだ保持しているセッションをドレインし、コントロールプレーンがそのセッションを別のランナーにすぐ再キューイングする |
どの段階でも、保持しているセッションがゼロになった時点でランナーは終了コード0で終了する。2回目のシグナルを受け取ると、この段階をスキップして即座にドレインが始まる(--defer-shutdown-max-minを使わない場合の、通常の1回目のシグナルと同じ扱い)。
ここで重要なのは、CHANGELOGが使っていた「park」という言葉の実体だ。ドキュメント本文は「解放(release)」という言葉を使っており、「a released session resumes on a fresh runner when its user sends their next message(解放されたセッションは、そのユーザーが次のメッセージを送った時点で、新しいランナー上で再開される)」と説明している。つまり「park」は、セッションを完全に停止させるのではなく、いったん手放して、ユーザーの次のアクションをきっかけに別の空いているランナーへ自然に引き継がせる、という挙動を指していたことになる。
ホスト側の停止タイムアウトを引き上げる必要がある
ドキュメントは、このオプションを設定する際の運用上の注意も具体的に書いている。
"Give your host's stop timeout at least the sum of three parts: the
nminutes you configure, the post-release grace, and the full drain path... With default settings the post-release grace is 75 seconds and the drain path is 80 seconds, so allownminutes plus 155 seconds."
(ホスト側の停止タイムアウトは、少なくとも3つの要素の合計以上に設定すること:設定したn分、解放後の猶予、そして完全なドレイン経路……デフォルト設定では、解放後の猶予は75秒、ドレイン経路は80秒なので、n分+155秒を確保すること)
もしこの停止タイムアウトが足りずホストがランナーを強制終了した場合、保持していたセッションはpost-sessionフックが実行されないまま終わり、ランナー自身もコントロールプレーンから正常に登録解除されず、そのセッションは約1分後に再キューイングされる、ともドキュメントは説明している。設定できる余裕がない場合は「--defer-shutdown-max-minを設定せず、最初のシグナルでドレインする従来の挙動のままにしておくこと」と、無理に使わない方が安全なケースも明記されている。
デフォルト値についても、リファレンスページで確認できた。--defer-shutdown-max-minのデフォルトは0で、これは機能そのものが無効であることを意味する(対応する環境変数はSELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS)。つまり、明示的にこのフラグを指定しない限り、ランナーは従来通りSIGTERMを受け取った時点でドレインを開始する。
同じリリースのegressプロキシ対応
v2.1.238の変更点一覧には、もう1つ自己ホストランナー関連のオプションが記載されていました(原文と訳)。
"Added
claude self-hosted-runner --proxy-authorization-command/--proxy-authorization-filefor egress proxies that require a freshly issuedProxy-Authorizationheader on every connection"(訳:
claude self-hosted-runner --proxy-authorization-command/--proxy-authorization-fileを追加。接続のたびに新しく発行されたProxy-Authorizationヘッダーを要求するegressプロキシに対応する)
これは、企業ネットワークで外部への通信(egress)がプロキシ経由に限定されており、かつそのプロキシが接続ごとに使い捨ての認証ヘッダーを要求する構成(短命トークンの発行など)に対応するためのオプションです。公式ドキュメント「Authenticate to an egress proxy」の節を確認すると、具体的な使い分けが説明されていました。--proxy-authorization-commandは「オンデマンドで生成するトークン」向けで、指定したシェルコマンドを実行しその標準出力(trim後)をヘッダー値として使う。--proxy-authorization-fileは「別のプロセスがその場でローテーションするトークン」向けで、指定したファイルの中身(trim後)を読み取る、という違いがあります。
このオプションを使うと、ランナーは127.0.0.1上に自前のフォワードプロキシ(リスナー)を起動し、ランナー自身・ライフサイクルフック・各セッションからのプロキシ通信をすべてそのリスナー経由に付け替えます。トークンのローテーションはランナーの再起動なしに反映され、リスナーがプロキシへの接続を開くたびに、指定したコマンド・ファイルを再実行・再読み込みしてヘッダーを付け直す、という仕組みです。ヘッダーの値自体はログに一切出力されない、とも明記されています。
なお、次の3つの構成ではランナー自体が起動を拒否する、という安全策も組み込まれています。①--proxy-authorization-commandと--proxy-authorization-fileの両方(環境変数側との組み合わせも含む)が同時に設定されている場合、②HTTPS_PROXY・HTTP_PROXYのいずれにも有効なプロキシURLが設定されていない場合(ALL_PROXYは見ない)、③self-hosted-runner orchestratorサブコマンドにこれらのフラグを渡した場合(オーケストレーター自体は非対応で、各ランナーに個別に渡す必要がある)。
トークン取得そのものが失敗した場合の挙動も、同じドキュメントの「Troubleshooting」節に記載があった(2026年9月4日に本文を取得し、502 Bad Gateway の記述の直前の見出しが ## Troubleshooting であることを確認)。--proxy-authorization-command・--proxy-authorization-fileで指定した取得元が失敗する、30秒でタイムアウトする、あるいは空の値を返した場合、ランナーはその接続に対して502 Bad Gatewayを返し、理由をログに記録する。コマンドの標準エラー出力はログ上でも伏せられ、ヘッダーの値自体は一切ログに出さない、という原則はここでも徹底されている。起動時にcould not start the proxy-authorization listenerというエラーで落ちた場合は、ループバックリスナー自体を開けなかったことを意味する、ともドキュメントは説明している。
自己ホストランナー関連の他の修正
同じv2.1.238のリリースノートには、自己ホストランナーの信頼性に関わる修正も複数含まれていました。
- 「自己ホストランナーが、1回の遅い・失われたポールリクエストだけでサーバー側から削除され、正常なセッションが別のランナーに渡されてしまう不具合を修正」
- 「stdio MCPサーバーが
initializeより前にserver/discoverリクエストを受け取り、遅延起動するサーバーがセッションを開くたびにバックエンドを起動させられていた不具合を修正」
これらは--defer-shutdown-max-minほど目立つ新機能ではありませんが、自己ホスト運用時の安定性に関わる細かい修正が同じリリースにまとまって入っている、という点は運用担当者にとって参考になる情報です。
自己ホストランナーを実際に運用して試したわけではない
- 筆者自身は自己ホスト型のClaude Codeランナーを運用しておらず、
--defer-shutdown-max-minや--proxy-authorization-commandを実際にコマンドラインで叩いて挙動を確認したわけではない。以下の解説は、公式ドキュメントの記載にもとづく - 「解放(release)」されたセッションが、実際にどれくらいスムーズに別のランナー上で再開されるか(体感の速さ、コンテキストの引き継がれ方)については、ドキュメントの記述以上の一次情報は持っていない
- ドキュメントが挙げている「デフォルト設定では解放後の猶予75秒・ドレイン経路80秒」という数字は、あくまでデフォルト値の場合の数字であり、
--drain-wait-secなど他のフラグを変更した場合にこの合計がどう変わるかは、本記事では計算例として紹介した範囲にとどめている - egressプロキシ認証機能について、実際に短命トークンを発行するプロキシ環境と組み合わせて動作を確認する検証は行っていない
関連記事
出典・参照資料
- 一次資料Release v2.1.238 — anthropics/claude-code(GitHub公式リリースノート) ↗
- 一次資料Self-hosted environments reference(公式ドキュメント、CLIフラグ・環境変数・デフォルト値の完全なリファレンス) ↗
- 一次資料Deploy self-hosted environments to production(公式ドキュメント、「Defer the drain past the first signal」節でシグナル後の3段階の挙動を解説) ↗
- 二次資料CHANGELOG.md — anthropics/claude-code(GitHubリポジトリ内の生Markdown版変更履歴、v2.1.238の全項目) ↗
更新・訂正履歴
- 記事の構成を修正。「3行まとめ」のブロックが連続して2つ置かれていた(量産時のテンプレート重複)。2つ目は公式ドキュメントで確認した内容(既定値0・parkはドキュメント上はrelease・ホスト側の停止タイムアウトを+155秒)なので、見出しを「公式ドキュメントで確かめた3点」に改めて役割を分けた。本文の技術的な記述は変えていない。
AIニュースの解説を動画でも
YouTubeでは注目ニュースの背景を解説し、Xでは新着記事をお知らせしています。
コメント
まだコメントはありません。最初のコメントを書いてみませんか?
AIについて聞きたいことはありますか?
質問箱で無料で受け付けています。回答は公開され、他の方の参考にもなります。
質問箱を見る →新しい記事をメールで受け取る
AIの新しい発表を、出典付きで整理して届けます。