コンテナ内では正常に見えるのに、Nginx/Caddy の背後では 502、WebSocket ハンドシェイク失敗、無限リダイレクト? 本文はエッジのリバースプロキシ + TLS 終端 + WebSocket アップグレードに絞る。Docker ネットワーク切り分けと補完関係で、そちらはパケットの到達性、こちらはブラウザから Gateway までの HTTP/1.1 アップグレード経路とパスを扱う。6 つの典型落とし穴、トポロジと症状の対照表、コピペ用スニペット、6 ステップの本番 Runbook、オンコール向け指標が 3 つ。読後は Upgrade を直すべきか、上流 127.0.0.1:18789 に戻るべきか判断できる。
proxy_pass だけで HTTP/1.1 と Upgrade がない:WebSocket 利用時にエッジで 400/502 になり、ログは Gateway 落ちに見える。/openclaw を剥がしてもアプリがルート基準の絶対 URL を出し、静的資産と WS パスが分裂する。proxy_read_timeout が短すぎる:長い推論やチャネルバーストでエッジが静かに切断し、再接続ストームが上流を直撃する。次のトポロジ表で同一ホスト/別ホスト/サブドメイン/サブパスのトレードオフを整理し、その後ヘッダチェックと症状マトリクスへ進む。
同一ホストのリバプロ(Nginx/Caddy と Gateway 同居)は最短経路で、curl -v http://127.0.0.1:18789 で上流を検証できる。別ホストはホップが増え、セキュリティグループ、内部 DNS、TLS SNI を再確認する。サブドメインはパス剥がしや Cookie Path の衝突を避けやすい。サブパスは単一ブランドホスト向きだが、OpenClaw のベース URL とプロキシの両方でプレフィックスは一度だけ剥がし、開発者ツールで WS URL が期待する wss:// を指すか確認する。
変更依頼にはスクリーンショットを 2 枚添付する:最終的なアドレスバーと、Network タブの WebSocket 握手 Request URL。無いとレビューがモデルタイムアウトやチャネル OAuth に誤分類され、リリース時間を浪費する。企業 HTTPS プロキシがある場合、オフィスブラウザ(PAC 注入)とデータセンターのリバプロ(多くは直結)を分けて考える。症状の不一致は普通に起きる。
2026 年もエッジ HTTP/2 と上流 HTTP/1.1 WebSocket の組み合わせは一般的。どのホップでアップグレードが許可されるかを確認する。パケット取得なしに強制 H2 とカスタム WS 書き換えを同時に有効にしないこと。
| トポロジ | 向く用途 | 運用メリット | 典型の落とし穴 |
|---|---|---|---|
| 同一ホスト + ループバック上流 | 単一 VPS / 常時稼働リモート Mac | ローカル curl で切り分け、TLS とプロセスが同じログ | 0.0.0.0 バインドで露出が増える。FW で抑える |
| 専用リバプロホスト | 多バックエンド、ブルーグリーン、WAF 前置 | エッジと計算プールを分離、証明書更新を集中化 | 内部ルート、SNI、ヘルスチェック先のドリフト |
| サブドメイン | WS を本サイトから分離 | パス意味が明確、CDN ルールが書きやすい | 複数証明書、HSTS は別レビュー |
| サブパス | 単一ブランドエントリドメイン | ユーザーが覚えやすい | プレフィックス剥がし、リダイレクトループ、資産ルートのずれ |
どちらの実装でも、エッジは HTTP/1.1 へのアップグレード、Connection: upgrade と Upgrade: websocket の透過または再構築、そしてモデル最遅分位より長い読み取りタイムアウトが必要。表はコードレビュー用チェックリスト。
見落としがちなのはプロキシバッファ。通常 API では proxy_buffering がスループットに効くが、ストリーミングや長寿命接続では遅延や切断感を招く。ストリーム型チャネルや SSE 的挙動がある場合はステージングで実負荷をかけてからデフォルトバッファを有効にする。
| チェック | Nginx の要点 | Caddy の要点 |
|---|---|---|
| プロトコル版 | proxy_http_version 1.1; | reverse_proxy は既定で HTTP/1.1。明示 transport に注意 |
| Upgrade チェーン | Upgrade $http_upgrade; Connection "upgrade"; | 多くは自動。カスタムは header_up |
| Host とクライアント IP | proxy_set_header Host $host;、X-Forwarded-* | header_up Host {host}。プロキシホップの信頼 |
| 長寿命接続 | proxy_read_timeout / send_timeout | transport http { read_timeout ... }(版ごとの構文はドキュメント参照) |
| 大きなボディ | client_max_body_size | ボディ制限系ディレクティブ(Caddy ドキュメント参照) |
# スニペット: ローカル Gateway へリバプロ(ポートは環境に合わせる。例 18789)
location / {
proxy_pass http://127.0.0.1:18789;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
# スニペット: 自動 TLS + WebSocket 上流
openclaw.example.com {
reverse_proxy 127.0.0.1:18789 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
ヒント:設定変更後はまず上流側で curl -v -H "Connection: Upgrade" -H "Upgrade: websocket" http://127.0.0.1:18789/ により握手の意味を確認し、その後に公開 wss:// を試す。さもなくば TLS とプロキシの間で責任が往復する。
症状をエッジ・上流・アプリ設定にマッピングしてからコンテナを作り直す。表がコンテナネットワークを指すなら Docker ネットワーク切り分けへ。チャネルは繋がるが Slack/Telegram が沈黙なら チャネル接続トラブルシュートを参照。
本番だけ再現しステージングは正常なら、証明書チェーンの CA、CDN/WAF ルールの版、プロキシの map/if が User-Agent で分岐していないかを差分比較する。多くの 502 はエッジの誤検知で、OpenClaw の版とは無関係。
| 症状 | まず疑うもの | 検証 |
|---|---|---|
| 502 Bad Gateway | 上流未リッスン、FW、ソケット族の誤り | リバプロから上流へ curl。error.log の upstream timed out / refused |
| 413 Request Entity Too Large | エッジの client_max_body_size が小さい | 値を上げて reload。CDN/WAF 側の制限も同期 |
| WS が 101 にならない | Upgrade 欠落、パス書き換え、http→https リダイレクトが握手を壊す | ブラウザ Network で握手ステータス。location 順と return 301 |
| リダイレクトループ | X-Forwarded-Proto なしで HTTPS 強制 | テストでエッジ HSTS を一時緩和。Forwarded ヘッダを補完 |
| 証明書警告/一部クライアントのみ失敗 | チェーン欠落、誤 SNI、IP 証明書の混在 | openssl s_client -servername でチェーン確認。NTP |
https:// ベース、サブパス有無、WS が HTTP と同じ host かを文書化。18789)。127.0.0.1:18789 または内部 VIP まで。公遅延と切り離し、遅さがエッジか Gateway かを判断しやすい。集中ログがあるなら、リバプロ access の 5xx 率とGateway アプリのエラー率を二軸で並べる。片方だけが跳ねたとき責務境界が明確になり、ポストモーテムがデータで語れる。
ノート上のリバプロ実験はスニペット検証には速いが、スリープ、VPN 切替、不安定な家庭用アップリンクは TLS と更新を手作業にする。502 の SLO を契約に落とせない。リバプロ + 常時 Gateway を 24/7 の専用ホスト(例:レンタルの Apple Silicon クラウド Mac や管理下 VPS)に置けば、レート制限、証明書、ログ保持が標準変更になる。入口が安定して初めて OpenClaw と CI、署名パイプラインの連携が監査と引き継ぎに耐える。
自前リバプロスタックは OpenSSL、Nginx、OS の CVE 追従も必要。OpenClaw を CI、署名、マルチチャネル Bot に長期結びつけるチームにとって、予測可能な専有算力と明確なリージョン/契約期間は家庭用出口の実験より総コストで有利なことが多い。MACCOME のクラウド Mac は複数リージョンと明確なレンタル帯を提供し、TLS 終端の背後にあるクリーンな常駐機として適する。まず 3 プラットフォームのインストールと選定でディレクトリと権限境界を固め、Mac mini レンタル料金と地域ページ——シンガポール、東京、ソウル、香港、バージニア、シリコンバレー——で実行層を契約可能な環境へ移し、エッジのリバプロはポリシーと観測だけを担う。
接続、セッション、チャネル系の論点は ヘルプセンターでキーワード検索し、視覚的な切り分けにはリモートデスクトップや SSH/VNC の記事と組み合わせる。
よくある質問
502 のとき、プロキシと Docker のどちらを先に見る?
リバプロホストからループバック上流を curl。不通なら Docker ネットワーク切り分けへ。プラン比較は Mac mini レンタル料金。
サブパスとサブドメイン、どう選ぶ?
サブドメインは剥がし問題を避けやすい。サブパスは両側のベース URL を一致させる。インストールは 3 プラットフォーム インストールガイドで版を揃える。
CDN 越しに WS が落ちる
キャッシュを切る、アイドルタイムアウトを延ばす、制御面用サブドメインで CDN をバイパスする。チャネル側は Slack/Discord/Telegram 切り分けを参照。
ログとチケットはどこへ?
エンタープライズ変更は ヘルプセンターのチケットへ。本番チャットに Nginx 設定の半分を流さない。