単一ポートに束ねた OpenClaw ゲートウェイをそのまま再起動すると、進行中のツール呼び出しやストリーミング応答が途中で切れ、利用者からは「突然オフライン」に見えます。2026 年の運用では、旧バイナリを残したまま新ビルドを別のループバックポートで受け、nginx の upstream 重みで新規 TCP を徐々に送り替え、最後に旧プロセスだけを止める トラフィックドレイン が標準になりつつあります。本稿では macOS 上での具体的なポート割当、デフォルト秒数、openclaw doctor に沿った検証、失敗時の切り戻しを整理します。TLS やトンネルの置き方は リバースプロキシとトンネル強化、ドレインが破綻してハード再起動に落ちるケースは LaunchAgent からの復旧 とセットで読んでください。
想定読者は自前ホストで 24 時間ゲートウェイを動かす SRE と、社内 PoC をクラウド Mac に載せ替えたい開発者です。手順表・curl 例・観測指標まで一通り揃えています。
なぜ即時再起動では足りないか
ユーザーは遅い応答よりも、説明のつかない切断を嫌います。keep-alive が張られたままプロセスが死ぬと、ヘルスチェックが一瞬で緑でも「アシスタントが落ちた」というバナーが残ります。ドレインは TCP 上の意味を保ち、既存接続は旧バイナリで完走し、新規だけが緑へ流れます。
金融・コンプラの観点では、冪等性キーなしの自動リトライで二重課金イベントが起きるリスクもあります。120 秒のドレイン窓は、事後調整のコストに比べれば安い保険です。
社内チャットボットの PoC では、開発者が「とりあえず kickstart」で再起動しがちですが、運用に載せる段階でドレイン手順を Runbook 化しておかないと、夜間オンコールが毎回同じ切り分けに時間を溶かします。Runbook には Git のタグ、nginx reload の時刻、緑バイナリの SHA を必ず書き留めてください。
blue / green と nginx の位置関係
青を 127.0.0.1:8787、緑を 127.0.0.1:8788 にバインドする例です。外向きの 443 は nginx が受け、upstream に両方のループバックを登録します。定常時は青 100、展開中は 10 ポイントずつ緑へ移し、エラーバジェットを見ます。
| フェーズ | 青の重み | 緑の重み | オペレータの注視点 |
|---|---|---|---|
| 定常 | 100 | 0 | ベースライン指標 |
| カナリア | 90 | 10 | エラー率の同等性 |
| 中間 | 50 | 50 | レイテンシ分布 |
| 完了 | 0 | 100 | 青ソケットのドレイン |
セッション固定が必要なチャネルアダプタでは ip_hash や sticky cookie を検討しますが、その場合も「新旧で同じハッシュ空間か」を事前に確認してください。
nginx 設定のたたき台
設定は単純に保ちます。upstream は二つ、負荷が偏るなら least_conn。OpenClaw のログに元ホストを残すため proxy_set_header Host などは欠かさないでください。
upstream openclaw_gateway {
least_conn;
server 127.0.0.1:8787 weight=90 max_fails=3 fail_timeout=10s;
server 127.0.0.1:8788 weight=10 max_fails=3 fail_timeout=10s;
}
server {
listen 443 ssl;
location / {
proxy_pass http://openclaw_gateway;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_read_timeout 300s;
}
}
nginx -t && nginx -s reload でサブ秒リロードは可能ですが、ワーカー再生成ポリシーによっては既存接続に影響するため、メンテ窓の告知は別途運用ルールで決めてください。
エンドツーエンドで揃えるタイムアウト
proxy_read_timeout を 300 秒にしつつゲートウェイ内部を 60 秒にしていると、ログではモデル側のせいに見えても実際はプロキシが先に切っています。スプレッドシートで単一の真実を持ち、SRE とベンダサポートで共有してください。
WebSocket やストリーミング HTTP では該当ロケーションで proxy_buffering off を忘れないでください。デフォルト 4MB バッファが詰まり、ストールに見える事象を生みます。
ドレイン中に fail_timeout を短くしすぎると、CPU スパイク時に緑が不必要に外され、逆に長すぎると不良ビルドが残ります。M4 クラスの Apple Silicon で並列エージェントを動かす前提なら、失敗試行の回数と秒数はステージングで実測してください。
カナリア・検証・ロールバック
最初の 10% に進む前に、ループバック直叩きで合成チャットを流し、青との初トークンまでの時間を比較します。8% を超える劣化ならロールアウトを止めます。
nginx のアクセスログと OpenClaw の構造化ログに相関 ID を載せないと、ポストモーテムが感想大会になります。リクエスト ID をどちらにも通してください。
ロールバックは重みを 100/0 に戻し、緑プロセスを kill するだけです。月一回は演習して手が覚えている状態にしておくと、インシデント時に迷いません。
ステージングでは意図的に緑だけを遅延させるフラグを入れ、監視が色別にアラートを上げるかも合わせて確認してください。本番ではそのフラグを外し忘れるとノイズになります。
macOS のプロセスとポート
色ごとに LaunchAgent ラベルを分け、launchctl kickstop の対象を誤らないようにします。標準出力のパスも色で分けないと JSON ログが混線し、パーサが壊れます。
lsof -nP -iTCP:8787 -sTCP:LISTEN でリスナを確認し、ホットリロード後にゾンビポートが残っていないかを見ます。
本番に近い熱挙動と launchd の挙動を合わせるには、ノート PC より クラウド Mac mini(MacHTML では概ね 1 日 16.9 米ドル)の方が再現性が高いです。SSH で設定を編集し、VNC でメニューバーアイコンを見ながら切替を確認できます。
複数ユーザーで同じホストを共有する場合は、ホームディレクトリと API キーを混線させないよう、ゲートウェイの設定ディレクトリをユーザー単位で隔離してください。ドレインは公平性の問題を解決しません。
重み移動中の可観測性
切替中は 10 秒ごとに、色別アクティブ接続数、色別 5xx 比、合成プローブの p95 初トークン時間を出します。同じ軸に載せると人間がすぐ異常に気づけます。
Grafana に nginx reload 時刻と緑の Git SHA をアノテーションすると、後日の遅延増加を重みステップと結びつけやすくなります。
緑の 5xx が青より 0.5 ポイント長く、かつ 3 分以上続く場合は自動ロールバックを検討してください。YAML の複雑さよりインシデントコストの方が大きいことが多いです。
二重リスナー時のセキュリティ
ループバックが二つあると、0.0.0.0 への誤バインドリスクが倍加します。デプロイ後にリスニングアドレスを grep するチェックを CI に入れてください。
シークレットローテーションは両色が揃ってから重みを動かします。片方だけ古い API キーだと、緑に流れた瞬間に静かに失敗します。
管理用デバッグルートは両ビルドで無効化し、バージョン間のフラグ差分を攻撃面にしないでください。
マルチテナントと騒がしい隣人
テナント別レート制限は OpenClaw 設定と nginx の limit_req の両方で一貫させます。緑が誤って並列度を二倍にしている場合、ドレインしても公平性は戻りません。
大規模切替はディスクスナップショットの cron と重ならないようスケジュールしてください。APFS のコピーオンライトが尾を引き、レイテンシに無関係なスパイクが出ます。
初回本番ドレイン時の Grafana 録画は、次のオンコール研修にそのまま使えます。文章の Runbook より効きます。
FAQ
ドレインすればエラーはゼロになりますか?
いいえ。アプリのバグは残りますが、トランスポートリセットのクラスは減らせます。
TCP の代わりに Unix ドメインソケットは使えますか?
はい。nginx の unix: upstream でも同じ重み付けが使えます。
上流モデルへの mTLS は?
両色で同じ終端/パススルー方針にしてください。混在すると TLS ハンドシェイクのログだけが紛らわしくなります。
常時稼働のゲートウェイでは、専用ハードの経済性も重要です。Mac mini は待機電力が低く、切替中も二色分のプロセスに余裕がある構成が取りやすいです。MacHTML のレンタルなら調達待ちなく検証用ホストを増やせ、本番とは別に nginx reload のリハーサル専用機を立てられます。リリース週だけ台数を増やすといった弾力的な使い方が現実的です。