Xserver VPSのDocker環境(Dify + n8n)にOpenClawを追加してLINE Bot化する全記録
Xserver VPSのDocker環境(Dify + n8n)にOpenClawを追加してLINE Bot化する全記録
誰かの役に立つように書き残す。ただし正直、これを再現できる人がどれだけいるかは分からない。ハマりポイント10個、所要時間6時間の記録。
背景
Xserver VPS上でDifyとn8nがDocker Composeで同居している環境に、OpenClawを追加。LINE Messaging API経由でAIエージェントとして動かし、LINEに話しかけるとAIが返事する構成を作った。
OpenClawの設計思想
OpenClawの創始者Peter Steinbergerは「ローカルファースト」のアーキテクチャを意図的に構築している。ただし「ローカル」とは「個人のMac限定」ではなく、「ユーザーが管理するインフラ上で動かす」という意味。ノートPC、Mac Mini、ラズパイ、VPS、全てが想定対象。公式スローガンは "Your assistant. Your machine. Your rules."
つまりVPSでの運用は公式に想定された構成の一つ。ただしDockerでのデプロイは別問題で、Dockerのネットワーク分離とOpenClawのセキュリティモデル(localhost以外を疑う設計)の相性が悪い。 これが今回のハマりポイントの大半の根本原因。
参考: Fortune - Who is OpenClaw creator Peter Steinberger?
参考: Y Combinator独占インタビュー
最終構成
- Xserver VPS(RAM 6GB)
- Docker Compose で Dify + n8n + OpenClaw が同居
- NginxはDify付属のコンテナ(パスベースでルーティング)
- LLMはOpenRouter経由(Claude Haiku 4.5)
- LINEから話しかけるとAIが返事する
所要時間
約6時間(ハマりポイント10個)
1. docker-compose.yaml にサービスを追加
既存の docker-compose.yaml に追記:
# OpenClaw
openclaw:
image: ghcr.io/openclaw/openclaw:latest
container_name: docker-openclaw
restart: unless-stopped
ports:
- "18789:18789"
volumes:
- ./openclaw/data:/root/.openclaw
environment:
- OPENCLAW_GATEWAY_PORT=18789
networks は既存サービスと同じに合わせる。指定なしならデフォルトネットワーク。
docker compose up -d openclaw
DifyやN8nは触らない。 個別サービスを指定して安全に追加する。
2. Nginx設定にlocationを追加
templateファイルの場所を特定
Dify付属のNginxは default.conf.template から設定が生成される:
docker inspect <nginx-container> --format='{{json .Mounts}}' | python3 -m json.tool | grep -A3 "conf.d"
最終的なNginx設定(完成形)
templateファイルに以下を追記:
# OpenClaw ダッシュボード
location /openclaw/ {
proxy_pass http://openclaw:18789/;
include proxy.conf;
include /etc/nginx/conf.d/ws-upgrade.conf;
}
# OpenClaw WebSocket(末尾スラッシュなし対応)
location = /openclaw {
proxy_pass http://openclaw:18789;
include proxy.conf;
include /etc/nginx/conf.d/ws-upgrade.conf;
}
# LINE Webhook
location /line/webhook {
proxy_pass http://openclaw:18789/line/webhook;
include proxy.conf;
}
WebSocket設定の共通化
n8nとOpenClawでWebSocket設定を共有するため、共通ファイルを作成:
cp nginx/conf.d/n8n-ws.conf nginx/conf.d/ws-upgrade.conf
中身:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
⚠️ ハマりポイント①:WebSocketヘッダーでNginx死亡
proxy_set_header Upgrade $http_upgrade; を直接templateに書くとNginxが起動しなくなる。Difyのtemplateは envsubst で処理されるため、$http_upgrade が環境変数として解釈されて空文字になる。必ず別ファイルに切り出してincludeすること。
⚠️ ハマりポイント②:WebhookパスはOpenClawのバージョンで違う
多くの記事では /webhooks/line と書かれているが、実際のパスは /line/webhook だった(v2026.4.2)。
# POSTで400が返るのが正解。404は間違い。
curl -s -o /dev/null -w "%{http_code}" -X POST http://localhost:18789/line/webhook \
-H "Content-Type: application/json" -d '{"events":[]}'
GETで200でもPOSTでNot Foundになることがある。必ずPOSTでテストすること。
⚠️ ハマりポイント③:proxy_passのホスト名
Docker内ネットワークなので localhost ではなく docker-composeのサービス名(openclaw)を指定。
⚠️ ハマりポイント④:ダッシュボードのWebSocket 1006エラー
ダッシュボードのJSが wss://domain/openclaw(末尾スラッシュなし)でWebSocket接続する。location /openclaw/ だけではマッチせず、ルートの / にフォールして502になる。
解決策:location = /openclaw(完全一致)を追加する。 ただし proxy_pass に末尾スラッシュをつけてはいけない。つけるとInternal Server Errorになる。
3. gateway.bindを変更する(502対策)
デフォルトではOpenClawは 127.0.0.1(loopback)でしかリッスンしない。Docker環境ではNginxは別コンテナなので502になる。
docker exec docker-openclaw openclaw config set gateway.bind "lan"
docker compose restart openclaw
ログで listening on ws://0.0.0.0:18789 になっていれば成功。
注意: gateway.bind "0.0.0.0" は旧バージョンの書き方。v2026.4.2では lan / loopback / tailnet / auto のモード指定に変わっている。
4. trustedProxiesを設定する(最重要)
⚠️ ハマりポイント⑤:Docker環境の「pairing required」地獄
OpenClawはlocalhostからの接続だけを信頼し、それ以外は全てペアリングを要求する。Dockerでは全てのリクエストが 172.18.x.x(Dockerの内部NAT)経由になるため、ダッシュボードもLINE Webhookも全部拒否される。
- DifyやN8nではこの問題は起きない(ペアリングという概念がそもそもない)
- OpenClawのセキュリティモデルは「自分のマシンで動かす」前提で、localhostを信頼する設計。VPS直接インストールなら問題にならないが、Dockerのネットワーク分離がこの前提を崩す
- GitHub Issues にも同じ報告が多数ある(#4531, #4941, #6959)
docker exec docker-openclaw openclaw config set gateway.trustedProxies '["172.18.0.0/16"]'
docker compose restart openclaw
172.18.0.0/16 はDockerの内部ネットワーク。インターネットからは到達できないのでセキュリティ的に問題なし。
5. 初期セットアップ(onboard)
docker exec -it docker-openclaw openclaw onboard
対話ウィザードで設定:
- モデルプロバイダー: OpenRouter
- モデル: anthropic/claude-haiku-4.5(速くて安い。LINE Bot向き)
- APIキー: OpenRouterのAPIキー
- LINEチャネル: Channel Access TokenとChannel Secret
⚠️ ハマりポイント⑥:Channel Access Token を間違える
LINE Developersコンソールには似た値が複数ある:
- Channel ID(数字だけ、短い)→ これではない
- Channel Secret(英数字、32文字程度)→ Basic settingsタブ
- Channel Access Token(非常に長い文字列)→ Messaging APIタブの一番下「Issue」で発行
Channel IDをAccess Tokenと間違えると401エラーになる。確認方法:
docker exec docker-openclaw curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer <トークン>" https://api.line.me/v2/bot/info
# 200ならOK、401ならトークンが間違ってる
6. ペアリング(2種類)
OpenClawにはdevicesペアリングとLINEペアリングの2種類がある。
ダッシュボード用(devices)
ブラウザでダッシュボードにアクセスすると承認を求められる:
docker exec docker-openclaw openclaw devices list
docker exec docker-openclaw openclaw devices approve <Request ID>
SSHトンネル経由とNginx経由は別デバイスとして認識されるので、それぞれ承認が必要。
LINE用(pairing)
LINEで初めてメッセージを送るとペアリングコードが返ってくる:
docker exec docker-openclaw openclaw pairing approve line <コード>
7. LINE側の設定
LINE Developersコンソール(developers.line.biz)
- Messaging APIチャネル作成
- Channel Access Token発行(Messaging APIタブ一番下の「Issue」)
- Channel Secretコピー(Basic settingsタブ)
- Webhook URL:
https://your-domain/line/webhook
LINE公式アカウントマネージャー(manager.line.biz)
- 応答設定 →「チャット」→ オフ
- 応答設定 →「Webhook」→ オン
- 自動応答メッセージ → オフ
8. ダッシュボードへのアクセス(2つの方法)
方法A:SSHトンネル経由
ssh -i ~/.ssh/your_key -N -L 18789:127.0.0.1:18789 root@<VPS-IP>
ブラウザで http://localhost:18789/#token=<gateway-auth-token>
方法B:Nginx経由(SSHトンネル不要)
controlUi.allowedOrigins に外部ドメインを追加:
docker exec docker-openclaw openclaw config set gateway.controlUi.allowedOrigins \
'["http://localhost:18789","http://127.0.0.1:18789","https://your-domain"]'
docker compose restart openclaw
ブラウザで https://your-domain/openclaw/#token=<gateway-auth-token>
トークンの取得:
docker exec docker-openclaw openclaw dashboard
9. セキュリティメモ
- インターネットに晒されるのはNginx(443)だけ。OpenClawの18789はDockerネットワーク内のみ
- Gateway Tokenはダッシュボードログイン用。初回起動時に自動生成
- サードパーティスキルは入れない(Ciscoのセキュリティ研究でデータ漏洩事例が報告されている)
- OpenRouterのAPIキーは専用に発行し、上限額を設定
- controlUi.allowedOriginsは必要なドメインだけに絞る
10. 容量とリソース
| コンポーネント | ディスク | RAM |
|---|---|---|
| OpenClaw本体 | 約500MB | 300〜500MB |
| Dify | - | 1〜2GB |
| n8n | - | 300〜500MB |
| OS等 | - | 300〜500MB |
Xserver VPSのRAM 6GBプランなら3サービス同居可能。
ハマりポイント一覧
| # | 問題 | 原因 | 解決策 |
|---|---|---|---|
| 1 | Nginx起動しない | $http_upgrade がenvsubstで空文字に |
別ファイルに切り出してinclude |
| 2 | 502 Bad Gateway | OpenClawがloopbackでしかリッスンしてない | gateway.bind "lan" |
| 3 | pairing required | DockerのNATでlocalhostに見えない | trustedProxies + devices approve |
| 4 | Webhook POST 404 | パスが /webhooks/line ではなく /line/webhook |
POSTでパスを検証 |
| 5 | LINE Access Token 401 | Channel IDをAccess Tokenと間違えた | 正しいTokenを再発行 |
| 6 | LINE返信来ない | LINEペアリング未承認 | pairing approve line <code> |
| 7 | ダッシュボード1006 (pairing) | devicesペアリング未承認 | devices approve |
| 8 | ダッシュボード1006 (WebSocket) | JSが末尾スラッシュなしでWS接続 | location = /openclaw を追加 |
| 9 | ダッシュボード origin拒否 | allowedOriginsに外部ドメインがない | allowedOriginsに追加 |
| 10 | ローカルLLMのハルシネーション | qwen2.5:3bが「公式クラウドゲートウェイ」を捏造 | 公式ドキュメントでダブルチェック |
感想
OpenClawは「ローカルファースト」の設計思想で作られており、ノートPC・Mac Mini・VPS・ラズパイなど「ユーザーが管理するインフラ」での動作が想定されている。VPSでの運用は公式に想定された構成の一つ。
ただし、Docker Compose環境での運用は茨の道だった。 ハマりポイントの大半(gateway.bind、trustedProxies、devices approve)はDockerのネットワーク分離とOpenClawのセキュリティモデル(localhostを信頼する設計)の相性問題。VPSに直接インストール(Docker不使用)すればこれらの問題の大半は回避できたはず。
既にDify + n8nがDocker Composeで動いている環境に追加するという今回の構成は、「Docker特有の問題」を踏み越える必要があった。
一度動いてしまえばLINEから話しかけるだけでAIエージェントが使えるのは非常に強力。VPSなのでMacがスリープしても24/7動き続ける。
エンジニアでない人にOpenClawを使ってもらう一番の方法は、VPSに構築してLINEのBotとして提供すること。使う側はLINEを友だち追加するだけで良い。
参考リンク
- OpenClaw × LINE公式アカウント連携完全ガイド
- OpenClaw公式ドキュメント
- 普段使いPCを汚さずにOpenClawを試す方法(GCP)
- Docker環境のpairing required問題(GitHub Issue #6959)
- Simon Willison - Running OpenClaw in Docker
- Fixing OpenClaw Docker's Pairing Required Dead End
- Fortune - Who is OpenClaw creator Peter Steinberger?
- Y Combinator独占インタビュー - OpenClaw設計思想
⚠️ ハマりポイント⑪(最重要):ボリュームマウント先の間違い
OpenClawの公式Dockerイメージはnodeユーザーで動作し、設定は /home/node/.openclaw/ に保存される。しかし多くのガイドや自分の最初の設定では /root/.openclaw にマウントしていた。
# ❌ 間違い — ここには設定が保存されない
volumes:
- ./openclaw/data:/root/.openclaw
# ✅ 正しい — nodeユーザーのホームディレクトリ
volumes:
- ./openclaw/data:/home/node/.openclaw
これが間違っていると、コンテナを再作成するたびに全ての設定(gateway.bind、trustedProxies、LINEチャネル、gogのOAuth認証データ等)が消える。 最も被害の大きいハマりポイント。
同様にgogcliの設定は /home/node/.config/gogcli/ に保存されるので、これも永続化が必要:
volumes:
- ./openclaw/data:/home/node/.openclaw
- ./openclaw/gogcli:/home/node/.config/gogcli
⚠️ ハマりポイント⑫:gogバイナリの永続化
docker cp や docker exec でコンテナ内にインストールしたバイナリは、コンテナ再作成で消える。永続化ボリューム内にバイナリを置くこと。
# ❌ コンテナ再作成で消える
docker cp /tmp/gog docker-openclaw:/home/node/.local/bin/gog
# ✅ 永続化ボリューム内に置く(消えない)
mkdir -p /root/dify/docker/openclaw/data/bin
cp /tmp/gog /root/dify/docker/openclaw/data/bin/gog
chmod +x /root/dify/docker/openclaw/data/bin/gog
# コンテナ内からは /home/node/.openclaw/bin/gog で参照
docker-compose.yaml 最終形
openclaw:
image: ghcr.io/openclaw/openclaw:latest
container_name: docker-openclaw
restart: unless-stopped
ports:
- "18789:18789"
volumes:
- ./openclaw/data:/home/node/.openclaw # ← /root/.openclawではない!
- ./openclaw/gogcli:/home/node/.config/gogcli # gogのOAuthトークン永続化
environment:
- OPENCLAW_GATEWAY_PORT=18789
env_file:
- ./openclaw/.env # GOG_ACCOUNT, GOG_KEYRING_PASSWORD
.envファイル(./openclaw/.env)
GOG_ACCOUNT=your-email@gmail.com
GOG_KEYRING_PASSWORD=your-keyring-password
chmod 600 で自分だけ読める権限に。
最終ハマりポイント一覧(12個)
| # | 問題 | 原因 | 解決策 |
|---|---|---|---|
| 1 | Nginx起動しない | $http_upgrade がenvsubstで空文字に |
別ファイルに切り出してinclude |
| 2 | 502 Bad Gateway | OpenClawがloopbackでしかリッスンしてない | gateway.bind "lan" |
| 3 | pairing required | DockerのNATでlocalhostに見えない | trustedProxies + devices approve |
| 4 | Webhook POST 404 | パスが /webhooks/line ではなく /line/webhook |
POSTでパスを検証 |
| 5 | LINE Access Token 401 | Channel IDをAccess Tokenと間違えた | 正しいTokenを再発行 |
| 6 | LINE返信来ない | LINEペアリング未承認 | pairing approve line <code> |
| 7 | ダッシュボード1006 (pairing) | devicesペアリング未承認 | devices approve |
| 8 | ダッシュボード1006 (WebSocket) | JSが末尾スラッシュなしでWS接続 | location = /openclaw を追加 |
| 9 | ダッシュボード origin拒否 | allowedOriginsに外部ドメインがない | allowedOriginsに追加 |
| 10 | ローカルLLMのハルシネーション | qwen2.5:3bが「公式クラウドゲートウェイ」を捏造 | 公式ドキュメントでダブルチェック |
| 11 | 設定が全部消えた | ボリュームマウント先が /root/.openclaw(間違い) |
/home/node/.openclaw に修正 |
| 12 | gogバイナリが消えた | コンテナ再作成でコンテナ内のファイルが消える | 永続化ボリューム内(/home/node/.openclaw/bin/)に置く |
⚠️ ハマりポイント⑬:環境変数が設定ファイルを上書きする
docker-compose.yamlの environment に OPENCLAW_GATEWAY_BIND=0.0.0.0 を書いていると、CLIで openclaw config set gateway.bind "lan" しても毎回上書きされる。しかも 0.0.0.0 は旧バージョンの書き方で新バージョンでは無効 → loopbackにフォールバック → 502。
「何度直しても元に戻る」場合は、docker-compose.yamlの環境変数を疑え。 環境変数は設定ファイルより優先される。
# ❌ これが残っていると設定ファイルを上書きする
environment:
- OPENCLAW_GATEWAY_BIND=0.0.0.0
# ✅ 削除して、設定ファイル(openclaw.json)で管理する
# gateway.bind は openclaw config set で設定済み