mem_limit · healthcheck と start_period · restart のバックオフ · json-file ローテとディスク監視
VPS 24/7 で OpenClaw を運用するチームが踏みがちな落とし穴は三つです。コールドスタートの Gateway を短すぎる healthcheck が殺すこと、WASM ピークより低い mem_limit による Exit 137、そして無制限の json-file ログによるディスク枯渇です。本文では開発用 compose と本番用 compose の最小差分、六段階の再現ベースライン、そして再起動ジッターで人が止める条件を整理し、Exit 137 と allowedOrigins の調査記事およびイメージ固定とロールバックへ相互リンクします。
開発環境では上限なしのメモリ、短いヘルス間隔、コンソールへのログが普通ですが、無人運用では再起動ストームに化けます。Gateway がまだ待ち受けていない段階で unhealthy になり、restart: always が秒単位で立ち上がり、バックオフより先にログや inode を食いつぶします。
OpenClaw は初回コンパイルとモデル読み込みで RSS が跳ねます。mem_limit を定常平均だけで決めると、夜間に OOM killer が静かにプロセスを落とします。ここでは各パラメータを docker inspect やホスト指標に結び付けられるようにします。
start_period が短すぎる: 18789 が開く前にプローブが失敗し、画面は再起動のループに見えます。
mem_limit とピークの乖離: 初回 WASM や依存取得のスパイクが cgroup を超え、137 で落ちる一方アプリログは薄い。
json-file の無制限増加: コールバックとデバッグログが PR 検証の忙しさと一緒にルートを埋めます。
バックオフのない restart: 設定ミスと誤判定が重なり CPU と IO を同時に飢餓させます。
開発用バインドマウントを本番へ: ホットリロードと緩い権限がシークレット面を広げます。
同一リポジトリの二枚の override を前提にします。docker-compose.yml に共通定義を置き、docker-compose.prod.yml には本番差分だけを足してコピペドリフトを防ぎます。
| 観点 | 開発のデフォルト | 本番ベースライン |
|---|---|---|
| メモリ | 上限なしまたはホスト全体 | 明示的な mem_limit とコールド余裕。Exit 137 記事と突合 |
| ヘルスチェック | 短い interval、start_period なし | start_period でコールドを覆う。retries と timeout を SLA 言語に合わせる |
| 再起動 | unless-stopped または無し | on-failure か上限付き always とホスト側アラート |
| ログドライバ | json-file 既定など | max-size + max-file。手動 truncate に依存しない |
| ボリュームと秘密 | ソースツリーのバインド | 設定は読み取り専用マウント。秘密は env_file か secret。イメージ層に載せない |
本番だけの行は Grafana かチケットの項目に必ず写せるべきで、願い事リストで終わらせない。
手順はイメージを固定の手順に従っていることを前提にします。:latest のままなら、staging で一度フルコールドを計測してから本番 override に移してください。
ピークを採る: staging で docker stats --no-stream とコンテナ内 ps を使い、初回 Ready の前後 10 分の RSS を記録します。
mem_limit を書く: ピークに合意した安全係数を掛けて compose に反映。swap 方針も文書化し silent OOM を避けます。
レディネスを定義: Gateway がバインドするループバックと同じ経路を HTTP か CMD で叩きます。
start_period を置く: 初回依存取得と WASM コンパイルを覆う長さ。平均ではなくコールド p95 を基準にします。
json-file を締める: サービスごとに logging を宣言し max-size と max-file を設定。ログディレクトリの増加率も監視します。
再起動訓練: 失敗プローブを一度入れ、間隔・バックオフ・ページングが手順書と一致するか確認します。
services:
openclaw:
mem_limit: "2g"
logging:
driver: json-file
options:
max-size: "20m"
max-file: "5"
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:18789/health"]
interval: 30s
timeout: 5s
retries: 5
start_period: 180s
restart: on-failure:5
注: 実際のパスはイメージに合わせます。HTTP が難しければ CMD-SHELL と nc も可ですが、HTTP より誤検知が増えやすいことをチケットに残します。
docker events が手順書のしきい値を超えて再起動を報せるなら、まず設定ミスと誤った unhealthy を疑います。RAM 不足だけを疑って再起動を続けるとログ書き込み増幅が悪化します。
ルートが読み取り専用なら、まずトラフィックを切るかリバプロを止め、Exit 137 の記事の順で空きを確保します。ディスク健全性を確認する前に compose up -d でボリュームを上書きしないでください。
注意: max-file を下げるとホットログが早く回収されます。長期保管が必要ならオブジェクトストレージやログホストへ送り、単一ファイルを無制限に肥大化させないでください。
リリースを凍結: ストーム中はデプロイ入口を止めます。
状態を採取: inspect の Health と OOM 断片と直近 200 行のログを残します。
compose を戻す: 直前の override に戻し、再現パックをポストモーテム用に保管します。
以下はプロジェクト憲章とオンコールの出発値です。実際のコールドスタート分布とディスク増加曲線で置き換え、顧客向け SLA として売り文句にしないでください。
同じ VPS にリバプロや小さな DB も載せる場合、mem_limit とログ IO は隣接プロセスと競合します。レビューではコンテナ RSS、ホスト空きメモリ、ディスク書き込み遅延を一枚のダッシュボードに載せることを要求してください。
| ホスト形 | ログの出発案 | イメージ固定との関係 |
|---|---|---|
| 2 vCPU / 4 GB | より小さい max-size、短い保持、積極的な転送 | digest 固定でコールド伸びのサプライズを防ぐ |
| 4 vCPU / 8 GB | max-file はやや緩めてもよいがローテは必須 | staging と prod は別タグでも同一 digest で検証 |
| 混合負荷 | データディスクやログ専用ボリュームで DB パーティションと分離 | アップグレード窓は固定記事と揃える |
小さな一時 VPS に OpenClaw を載せるとメモリとディスクと秘密のローテを同時に欠きます。自前ベアメタルは電源と回線 SLA のリスクと引き換えです。
契約された算力と選択可能なリージョンと監査可能な帯域が欲しく、24/7 で Gateway とチャネルを観測可能に保ちたいチームには、クラウド上の Mac Mini レンタルが現実的です。VpsMesh の Mac Mini クラウドレンタルは、compose 基準とリバプロとバックアップを一つのキャパシティ物語で受け入れやすいことが多いです。
プローブのユーザーと PATH、start_period がコールドを覆うか確認し、必要なら allowedOrigins とリバプロの記事でループバック経路を照合します。
ホストの dmesg と終了コードから入り、ピークを再計測してから limit を変えます。詳細は Exit 137 の記事。プラン比較は 価格ページ。
ローカルのホット保持は短くなります。長期保管は集中ログへ。方針は ヘルプセンター を参照してください。