小メモリの Ubuntu/Debian VPS では OpenClaw Gateway は動いていますが、Chromium を要するブラウザ系機能を有効にするとログにディスプレイなし・実行ファイルなし・サンドボックス関連のエラーが出ます。本稿は ヘッドレス Linux を本番 Gateway に据える担当者向けです。DISPLAY / Xvfb / browser.executablePath の暗黙の前提を 7 項目で洗い、仮想フレームバッファと実ディスプレイの運用コストを表で整理し、6 ステップの再現可能な Runbook(依存関係、Xvfb、環境変数、設定検証、systemd/Docker、最小受け入れ)を示します。併せて クロスプラットフォームインストール、not ready 切り分け、観測編 との役割分担を明確にします。
公式ドキュメントはディスプレイスタック付きマシンを想定しがちですが、本番では ヘッドレス VPS が一般的です。以下 7 つは「Chrome を入れれば足りる」という議論を、署名できるリスク表に落とし込みます。
Gateway プロセスがシェルの DISPLAY を自動継承すると思い込む:systemd の Environment= に無いと、ブラウザ子プロセスは空のディスプレイに乗ることがあります。
browser.executablePath をデスクトップ向けパスにする:コンテナや最小イメージではパスが異なり、spawn ENOENT 系に見えます。
フォントと ICU 依存を軽視する:フォントパッケージが無いと描画が静かに失敗したりタイムアウトし、Gateway が「固まった」ように見えます。
ブラウザサンドボックスを root で動かす:Chromium はサンドボックスを降格または拒否します。専用の非特権ユーザーにし、セキュリティ強化編 の最小権限と揃えます。
Xvfb と Gateway の起動順を固定しない:レースで初回ツール呼び出しが失敗し、リトライで「自己修復」します。再現が難しくなります。
ブラウザ RAM とモデル呼び出しを同じ予算に混ぜる:小さなマシンでは LLM より先に Chromium が OOM しやすいです。
Gateway ログだけ見て子プロセスの終了コードを見ない:ブラウザクラッシュは下流ではツールタイムアウトになります。openclaw logs とシステムジャーナルで時系列を揃えます。
共通の根は、ブラウザを任意プラグインではなく OS 依存チェーンを持つランタイム と見なさないことです。MCP ハンドシェイク編 はツール発見とセッション、本稿は ブラウザ実行ファイル+ディスプレイスタック の最小ループです。
Docker 本番 とベアメタル systemd を併用する場合、トポロジ図に DISPLAY と Xvfb を誰が起こすか書き、同じディスプレイ番号を奪い合わないようにします。
銀の弾丸はありません。再現性 と 切り分けの表面積 のトレードです。
| 観点 | Xvfb + DISPLAY | 実機 / VNC 表示 | Chromium --headless のみ(Xvfb なし) |
|---|---|---|---|
| 依存の幅 | Xvfb プロセス・ディスプレイ番号・フォントを保守 | セッション・解像度・人の介入ウィンドウを保守 | バージョンごとの headless 方針に依存、アップグレード後に振る舞いが変わることがある |
| 再現性 | 高:systemd ユニットや compose で環境変数を固定できる | 中:デスクトップセッションやロックの影響 | 中〜高:ディストリとサンドボックスの組み合わせ次第 |
| 切り分けシグナル | 明瞭:DISPLAY、Xvfb ログ、Chromium stderr | 複雑:GUI 状態と権限ダイアログ | 散発:GPU 無し環境で GPU/ANGLE 経路が踏みやすい |
| 典型用途 | 小メモリ VPS、スクリーンショット/自動化のみ | GUI 重いフローや署名ポップアップ | そのビルドで headless 単体が検証済みのツールチェーン |
ここで「再現可能」とは、同じ systemd ユニットまたは compose を清潔な VPS に持っていっても、Xvfb+Gateway+ブラウザが安定して立ち上がるという意味です。
not ready 編 と併用します。Gateway プロセスがまだ安定して待ち受けていないうちにブラウザ層の切り分けを重ねると、ログが混ざります。
順序は「ディスプレイスタック → Gateway → ツール」です。コマンドは Debian/Ubuntu 系の例で、他ディストリではパッジ名を置き換えます。
Chromium とフォント依存を入れる:apt install でディストリの chromium または google-chrome-stable と fonts-noto などを入れます。
Xvfb を入れる:Xvfb :99 -screen 0 1920x1080x24 を手動で起動でき、ソケット競合が無いことを確認します。
DISPLAY をエクスポートする:Gateway と同じ環境で DISPLAY=:99。systemd は Environment=DISPLAY=:99、Docker は environment ブロックです。
browser.executablePath を書く:which chromium またはパッジパスに合わせ、変更後に openclaw doctor(または同等)を実行します。
systemd または compose で起動順を固定する:Xvfb が先に Ready になってから Gateway。Xvfb に再起動ポリシーとログ出力を付けます。
最小受け入れ:Gateway が健全になったら about:blank だけ開くブラウザツールを一度走らせ、サンドボックス/ディスプレイエラーが無いことを確認してから本番トラフィックを開きます。
# 手动验证(维护窗): Xvfb :99 -screen 0 1920x1080x24 & export DISPLAY=:99 chromium --no-sandbox --disable-dev-shm-usage --headless=new --dump-dom about:blank >/tmp/blank.html # 然后以相同 DISPLAY 启动/重启 Gateway(systemd 或 docker compose)
ヒント: --no-sandbox は限定的な診断向けです。本番では非 root・最小権限と networkPolicy で露出を絞ります。
観測編 に合わせ、Xvfb と Chromium の stderr を同じチケットのタイムラインに載せ、「Gateway は緑だがツールは赤」をモデルバックエンドの問題と誤認しないようにします。
オンコールチャンネル用です。WebSocket クローズコードが絡む場合は gateway closed (1000) 編 へ移ります。
cannot open display: DISPLAY と生存中の Xvfb を確認します。executablePath ENOENT: パスとコンテナ内の同一バイナリのマウントを確認します。zygote / sandbox: 非特権ユーザーとカーネル側の前提を確認してから一時的な診断フラグを検討します。
注意: 寛容なサンドボックス設定を本番に長期置かないでください。診断後は設定を戻し、変更票を残し、監査要件に応じます。
Docker では /dev/shm と共有メモリ量も確認します。小さすぎると Chromium が間欠的に終了し、ツールが不安定になります。
セカンドラインとの突き合わせ用です。外部送付前にマスキングします。
/etc/os-release、uname -r、Chromium のメジャー版。ss -lxn | grep X11 または同等のリスナ確認。dmesg に OOM killer が無いか。Gateway をスリープしうるノートだけに縛るとディスプレイスタックもネットワークも不安定です。最小 VPS ではブラウザとモデルを同時に載せると OOM しやすいです。OpenClaw と周辺ツールチェーンのために 長期オンラインで契約上明確な macOS または専用算力が要るなら、専用リモート Mac の方が「とりあえず手元」より安定しやすいです。バラした自前機より、固定 SSH・明確なディスク段・再現しやすいノード像の NodeMini の Mac mini クラウドレンタル がガバナンスに向きます。仕様と料金は レンタル料金、接続は ヘルプセンター、連載は ブログの OpenClaw カテゴリ から入れます。
ブラウザ層が安定したら、今回の根本原因ラベルを変更記録に残し、次の Chromium アップグレードで同じ穴を踏まないようにします。
not ready はポート・メモリ・タイムアウト・コンテナ起動順です。本稿はブラウザサブシステムとディスプレイスタックです。続く場合は not ready 編 と closed (1000) 編 も照合してください。
ブログの OpenClaw カテゴリ からインストール、Docker、systemd、セキュリティ、観測、MCP へ進みます。オンボーディングは ヘルプセンター を参照してください。