2026 OpenClaw Docker Compose 連通與配對:1006/1008、TOKEN 對齊與 Unix Socket/共享名稱空間 Runbook

約 20 分鐘閱讀 · MACCOME

誰會遇到問題: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》《卷與許可權》可交叉跳轉。

Compose 分容器時常踩的五類「看起來像網路問題」的根因

  1. 把 Gateway 寫成 127.0.0.1127.0.0.1在每個容器裡是自己的迴環口,不會去另一個服務;必須用 Compose DNS 名(示例 http://openclaw-gateway:18789)。
  2. 雙 Token 源未對齊:環境變數OPENCLAW_GATEWAY_TOKEN 可能覆蓋配置檔案;兩側容器若各讀不同掛載副本,會表現為間歇 401/1008 交替出現
  3. Unix Socket 路徑未掛載到同一可讀卷:若閘道器透過 gateway.sock 暴露 Unix 域套接字,CLI 容器必須在完全一致的路徑掛載該 socket 或其父目錄,且許可權與 UID/GID 對齊(見卷許可權篇)。
  4. 1006 誤判成「偶發抖動」1006多表示非正常關閉鏈路——常見是閘道器重啟、超時、或被中間層拆掉;需要先對照同時間窗閘道器日誌是否重啟,不要直接改配對策略。
  5. 需要共享網路名稱空間卻走了預設 bridge:當文件要求 CLI 程序與 Gateway等價於同臺 loopback語義時,可在 Compose 用 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 父子目錄未同框掛載
warning

不要憑關閉碼做單點結論:1006/1008 在瀏覽器與 WebSocket 棧裡多半是症狀標籤;必須與閘道器日誌字首、配對狀態機、同一時間窗的反代 Retry並讀,否則容易被錯誤「擴大監聽面」或「反覆 onboard」帶進更大暴露。

落地六步:先「能看見閘道器」,再談配對是否成功

  1. 寫清單一真源的 Token:團隊先選配置檔案環境變數其一為權威出口,再在 CI 模版裡grep/docker compose config校對展開結果,杜絕「兩處各寫一半」。
  2. 統一閘道器地址語義:要麼全走Compose 服務名 + 埠;要麼(若官方文件支援 Unix)全走同一掛載下的 socket 路徑——兩套不要混在同一個變更單裡試執行。
  3. 掛載 .openclaw/執行時目錄:Gateway 與 CLI 必須看到同一份磁碟事實;狀態目錄只讀會直接讓配對「看起來永遠在第一步」,《卷與許可權對照》逐項過。
  4. 再跑閘道器健康與 doctor:openclaw gateway statusopenclaw doctor,失敗時把時間戳對齊到宿主與容器兩側的程序日誌
  5. 若確需等價 loopback:在評審單裡寫明採用 network_mode: service:<gateway> 或服務網格側替代方案,並在防火牆白名單上與《trustedProxies 篇》的引數一致。
  6. 收口變更證據:貼兩張截圖——CLI 名稱空間內的成功探測命令展開後的閘道器 URL/Token hash——再關票;口頭「我宿主 curl OK」不算驗收。

若團隊同時跑著外層 Nginx/Caddy,《反代與 WS》裡 Upgrade/Timeout 任一與 Compose 側的閘道器 URL口徑打架,會先表現為間歇 1006——這類問題只靠改 Gateway bind 往往會把暴露面鋪大還治標不治本。

yaml
# 佔位示例:請替換為你的服務名與實際路徑;合併前請先 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:

三條「應寫進變更單備註」的工程事實(與上游 SLA 無關)

  • 探測命令必須與故障容器同命名空間:否則永遠出現「宿主通、流水線不通」的薛定諤閘道器
  • Token hash 漂移應阻斷髮布:比人工肉眼對字串更靠譜的是兩邊的短指紋(檔案 hash/env inspect)一致。
  • 配對狀態與閘道器重啟強相關:若健康檢查過激導致頻繁重啟,會放大 1006,卻被誤改成擴大 bind—先用就緒探針與重啟策略收口。
  • 跨容器除錯的第一條戒律:任何「我本機試一下」的命令,如果沒進報錯容器映象執行,都只能算聊天,不計入 RCA。

為什麼「拼裝臨時容器」不適合長期承載 OpenClaw 閘道器主鏈路

筆記本上單容器試玩 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,是否等於流水線一定通?

不等於。必須在報錯同一容器映象裡執行等價探測;名稱空間不一致時宿主結果只是噪音。