誰會遇到問題:用 Docker Compose 把 Gateway 與 openclaw CLI 分到不同容器,日誌裡 Gateway 似乎在跑,CLI 卻卡在 gateway closed(WebSocket 1006/1008)、pairing required,或環境與檔案裡的兩處 Token互相打架。本文結論:這不是「重灌映象就能好」的一類問題,而要把閘道器 URL(服務名或 Unix Socket)、OPENCLAW_GATEWAY_TOKEN 與配置裡的 gateway.auth收斂到單一真源,並在必要時用共享網路名稱空間收斂呼叫面。分工:與《子代理配對與 trustedProxies》並列——那邊偏大類網段與白名單策略,本篇偏容器內如何「看見」閘道器與同源 Token;《Docker 網路分診》《配對與 Token》《卷與許可權》可交叉跳轉。
127.0.0.1:127.0.0.1在每個容器裡是自己的迴環口,不會去另一個服務;必須用 Compose DNS 名(示例 http://openclaw-gateway:18789)。OPENCLAW_GATEWAY_TOKEN 可能覆蓋配置檔案;兩側容器若各讀不同掛載副本,會表現為間歇 401/1008 交替出現。gateway.sock 暴露 Unix 域套接字,CLI 容器必須在完全一致的路徑掛載該 socket 或其父目錄,且許可權與 UID/GID 對齊(見卷許可權篇)。network_mode: service:<gateway>(佔位服務名),或接受「全部走服務名 TCP」的一致性架構——兩者勿混在同一套 env裡。把上述五條當作白板檢查項;任何一格仍待定,就不必先辯論「要不要換映象 tag」——網絡合同未閉合時換映象通常無效。
實戰中建議再補一欄時間線對齊:同一 WebSocket 關閉碼出現後,擷取毫秒級對齊的 Gateway stderr、CLI stdout、Docker events 三件事——半數「偶發」會被證明是另一側服務重啟或健康檢查誤殺。
| 症狀快照 | 優先核查(自上而下) | 常見落點 |
|---|---|---|
1006 + 閘道器程序剛重啟/OOM |
同一時間窗宿主 dmesg/Docker 重啟策略 → 再找上游超時與健康檢查 |
鏈路非正常關閉≠配對策略錯 |
1008 + pairing required |
對齊 Token 同源 → CLI 閘道器 URL → 配對狀態是否真的寫在共享卷 | 雙 Token 或未共享狀態目錄 |
Connection refused 僅在 CLI 容器內 |
把探測命令搬進 CLI 容器再跑;宿主 curl 僅能當旁證 | 127.0.0.1 誤區或埠未 publish 到 CLI 檢視 |
| 改用 Unix Socket 後 ENOENT/Permission denied | ls -la掛載點 → 宿主與容器 UID 對映 → 是否套娃目錄 |
socket 父子目錄未同框掛載 |
不要憑關閉碼做單點結論:1006/1008 在瀏覽器與 WebSocket 棧裡多半是症狀標籤;必須與閘道器日誌字首、配對狀態機、同一時間窗的反代 Retry並讀,否則容易被錯誤「擴大監聽面」或「反覆 onboard」帶進更大暴露。
grep/docker compose config校對展開結果,杜絕「兩處各寫一半」。.openclaw/執行時目錄:Gateway 與 CLI 必須看到同一份磁碟事實;狀態目錄只讀會直接讓配對「看起來永遠在第一步」,《卷與許可權對照》逐項過。openclaw gateway status → openclaw doctor,失敗時把時間戳對齊到宿主與容器兩側的程序日誌。network_mode: service:<gateway> 或服務網格側替代方案,並在防火牆白名單上與《trustedProxies 篇》的引數一致。若團隊同時跑著外層 Nginx/Caddy,《反代與 WS》裡 Upgrade/Timeout 任一與 Compose 側的閘道器 URL口徑打架,會先表現為間歇 1006——這類問題只靠改 Gateway bind 往往會把暴露面鋪大還治標不治本。
# 佔位示例:請替換為你的服務名與實際路徑;合併前請先 docker compose config 校驗展開
services:
openclaw-gateway:
environment:
- OPENCLAW_CONFIG_DIR=/data/.openclaw
# 若堅持用環境 TOKEN,請在所有消費方對齊同一 env_file
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
volumes:
- oc-data:/data/.openclaw
# 若啟用 Unix Socket,可把 socket 寫入該卷下可讀路徑並與 CLI 共享
networks: [oc-net]
openclaw-cli:
environment:
- OPENCLAW_CONFIG_DIR=/data/.openclaw
- OPENCLAW_GATEWAY_URL=http://openclaw-gateway:18789
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
volumes:
- oc-data:/data/.openclaw
networks: [oc-net]
depends_on:
- openclaw-gateway
networks:
oc-net:
driver: bridge
volumes:
oc-data:
筆記本上單容器試玩 Gateway 還可以;一旦進入常駐自動化 + 多端配對 + Secrets 輪換,漂移的 Docker 宿主、睡眠策略與零碎掛載會把 Token/配對狀態撕開。把 Gateway 固定在可數清重啟次數的獨佔節點上——例如六國可選、可按月/季組合的 Apple Silicon雲端 Mac——更利於與同區 CI Runner、金鑰管理節奏對齊:MACCOME提供更接近「小規模生產」的拓撲承載面;可先參閱公開租賃檔位與幫助中心,再回填本文 Runbook 中的環境欄位。
OpenClaw 在 Compose 場景的失敗模式幾乎總是網路名稱空間/Token/狀態目錄三件事未寫成一條合同。在未收斂單一真源前,不要盲目「換映象」「關 TLS」——會把排錯帶進安全債。評審會上若出現「先改程式碼還是先改基礎設施」的爭吵,用一句話壓制:哪一側能展示可重複的容器內握手成功包,就以哪一側的合同為準——其它討論一律排隊。
對齊後再與《GHCR Control UI Runbook》《反向代理與 TLS》做下一跳整合。
常見問題
本篇與 4 月《子代理配對 1008 + trustedProxies》有什麼分工?
那邊偏大網段、白名單與子代理鏈路;本篇把Gateway URL、TOKEN 同源、Unix Socket、共享名稱空間下的最短閉環寫清,兩邊應互聯閱讀而不是擇一丟棄。
宿主機能 curl 通 18789,是否等於流水線一定通?
不等於。必須在報錯同一容器映象裡執行等價探測;名稱空間不一致時宿主結果只是噪音。