2026 OpenClaw Docker 網路分診清單
CLI 連不上 Gateway——Compose 網路、bind 與命名空間對照修復

約 22 分鐘閱讀 · MACCOME

已用 Docker Compose 跑 OpenClaw的開發者裡,最高頻的挫敗往往不是「鏡像拉不下來」,而是Gateway 日誌看似正常、瀏覽器或 CLI 卻反覆報連接被拒絕 / WebSocket 失敗 / token 無效——其中大量案例根因在監聽地址(bind)、端口發佈、以及 CLI 與 Gateway 是否共享同一網路命名空間,而不是模型密鑰本身。本文給出六類可寫進值班的網路症狀、兩張「進程已起 vs 路由可達」對照表、bind/防火牆/發佈端口矩陣、可複製診斷命令、六步 Runbook 與三條應寫進日誌檢索的硬口徑;並與站內《Docker 與 Gateway 生產向 Runbook》《doctor 與裝後排錯》《K8s 探活與滾動更新》分工——生產篇管「怎麼部署」,本篇管「包在跑但包與包、包與宿主機之間為什麼互相看不見」

先把症狀分類:六類「像 token 問題、其實是網路」的假象

OpenClaw 的控制面通常由 Gateway WebSocket/HTTPCLI / Control UI 組成;Docker 場景下還會疊加 多個容器、自定義 bridge、以及 network_mode: service:... 等組合。若不做分層分診,團隊會在 .openclaw 與環境變量之間來回改,卻不去看監聽地址是否真的落在 CLI 可達的接口上。

  1. 僅 loopback 監聽:Gateway 在容器內只綁 127.0.0.1,宿主機通過 published port 訪問時由代理層轉發看似可通,但同 compose 內另一容器用服務名訪問時卻落到錯誤的協議視圖。
  2. CLI 與 Gateway 分屬兩個 network namespace:CLI 容器解析 gateway:18789 走了 bridge DNS,而 Gateway 實際只向 service 側暴露迴環套接字——表現為間歇性「第一次能連、重啟用後全掛」。
  3. published port 映射到錯誤 target:Compose 將宿主機 18789 指到舊容器 IP,滾動升級後 iptables 規則殘留,宿主機 curl 偶發成功、容器內始終失敗。
  4. 宿主機防火牆 / 雲安全組放行公網卻阻斷 bridge:本機 loopback 與 docker0 轉發策略不一致,導致「本機瀏覽器 OK、同機另一個 namespace 的 CLI 不 OK」。
  5. 反代或 Tunnel 只處理了 HTTP,沒升級 WebSocket:日誌裡出現握手失敗,常被誤判為 Gateway 崩了;實為路徑或 Upgrade 頭在邊緣被剝掉(與《Linux systemd + Tunnel》路徑互補)。
  6. 雙棧或強制 IPv6:容器內優先走 ::1 或錯誤 AAAA,宿主機僅 IPv4 通——在部分雲 Mac 或精簡鏡像上會被放大。

把上述條目與《生產 Runbook》裡的卷、鏡像標籤、健康檢查放在同一變更單上:前者回答控制面是否可達,後者回答進程是否按預期版本在跑

實務上建議在 compose 倉庫裡維護一頁「網路拓撲說明」:畫出 Gateway、CLI、可選的 edge 反代各自落在哪個 network、哪些端口由誰 publish、以及開發機與 CI 分別從哪裡探測。沒有這張圖時,排障對話會反覆落在「你是不是改了我本機的 hosts」這類不可審計路徑上。再補充一點:Docker 的 DNS 解析在自定義網路與預設 bridge 上行為並不相同,服務名解析失敗時不要先懷疑 OpenClaw 本身,先用 docker compose exec 進容器跑 getent hostsnslookup 確認名字是否落在預期 IP。

表 1:Gateway「未起」與「起了但不可路由」— 先判讀哪一類

第一步永遠用官方 CLI 做存活與版本對齊(見《doctor 篇》),再進入下表。不要在未確認進程監聽之前就改 token。

觀測更可能類別優先動作常見誤操作
docker ps 無 Gateway 容器或持續重啟未起 / CrashLoopdocker logs、資源限制、鏡像 digest、健康檢查是否誤殺反覆 docker compose pull 卻不看 OOM
容器 Running,但 ss -lntp(容器內)無監聽配置未加載 / 綁定失敗核對環境變量 OPENCLAW_GATEWAY_BIND 與 compose command;對照官方 Docker 文檔中的 bind 枚舉只改宿主機 /etc/hosts
容器內監聽正常,CLI 容器 wget 失敗跨 namespace 路由檢查是否應使用 network_mode: "service:gateway" 或統一自定義網路別名把 Gateway 改成 0.0.0.0 卻不理解暴露面
僅宿主機瀏覽器失敗、容器內成功端口發佈 / 本機代理核對 ports: 映射、本機 VPN/代理、以及是否誤用 localhost 解析到代理 PAC盲目關閉 Gateway TLS 選項

表 2:gateway.bind、端口發佈與防火牆—對照矩陣(Docker 專用讀法)

下列讀法與官方文檔中「bind 取 loopback / lan / tailnet / auto 等枚舉」一致;Compose 裡還要把誰負責 publish寫清。

目標典型 bind / 環境變量思路Compose 注意點安全邊界
僅本機開發機自測偏向 loopback;由宿主機瀏覽器訪問 published port127.0.0.1:18789:18789 限制暴露面不要把 loopback 誤當成「同 compose 其他服務預設可達」
同 compose 內 CLI 與 Gateway 強一致讓 CLI 共享 Gateway 的網路棧network_mode: "service:openclaw-gateway"(服務名以你的文件為準)共享棧意味著共享端口空間;避免重複監聽衝突
局域網其他設備調試lan 或等效;確保監聽非僅 127.0.0.1明確 ports 綁定 0.0.0.0 還是宿主機具體 IP配合上遊防火牆最小放行
經 Tunnel / 反代對外Gateway 僅迴環,邊緣終止 TLS分離 gatewayedge 網路;校驗 WebSocket 透傳禁止把管理口直接對公網裸暴露
bash
# 1) 宿主機:端口是否真的發佈成功
docker compose ps
curl -sv --max-time 2 http://127.0.0.1:18789/  || true

# 2) 進入 gateway 容器查看監聽(鏡像若有 ss/busybox 則用之)
docker compose exec openclaw-gateway sh -lc 'ss -lntp 2>/dev/null || netstat -lntp'

# 3) 從「CLI 容器」視角探測(服務名替換為你的 compose service)
docker compose exec openclaw-cli sh -lc 'wget -qO- --timeout=2 http://openclaw-gateway:18789/ || echo FAIL'

# 4) 對照網路命名空間(是否應 network_mode: service:...)
docker compose config | sed -n '1,200p'
warning

注意:社區 issue 中常見「CLI 無法連接 Gateway」與 compose 未讓 CLI 與 Gateway 共享網路命名空間相關:修改前先在測試 compose 上驗證第三節命令塊,再合併到生產文件。

六步 Runbook:從「能復現」到「能寫進變更記錄」

下列步驟假設你已能拉取鏡像;若尚未完成安裝入口,請先讀《三平臺安裝與平臺選擇》。

  1. 凍結 compose 片段:把 Gateway、CLI(若有獨立服務)、卷掛載與環境變量導出為單一 Git 版本,避免「手改運行態」與倉庫不一致。
  2. 跑 doctor 與 gateway status:確認版本與配置路徑一致,排除 token 文件多份(與《裝後排錯》對齊)。
  3. 按表 1 區分未起 vs 不可路由:對 Running 容器執行監聽檢查與跨容器 wget/curl
  4. 按表 2 調整 bind 與 network_mode:一次只改一個變量;每步重跑第三節命令塊留證據。
  5. 若經 Tunnel/反代:在邊緣抓 Upgrade 與路徑重寫,再回到 Gateway 日誌對照(與 Tunnel 篇分工)。
  6. 寫入值班主任摘要:記錄「監聽地址、compose service 名、是否共享 network namespace、以及一條成功的探測命令輸出摘要」。

三條應寫進日誌檢索與告警的「硬核」口徑

下列欄位把「偶發連不上」變成可對比迴歸的信號,並與《K8s 探活篇》中的 HTTP 探針欄位兼容(遷移到編排時可直接映射)。

  1. 監聽三元組:容器內 ss 輸出的 Local Address:Port + 進程名 + compose 服務名;任一變更必須出現在變更單。
  2. 跨命名空間探測結果:CLI 容器到 Gateway 的 HTTP/TCP 結果(成功/超時/DNS 失敗)分桶統計;DNS 失敗與連接超時是不同根因。
  3. 端口發佈一致性:宿主機 docker port 與實際 iptables NAT 規則是否在滾動後仍指向當前任務 IP;2026 年常見「升級後舊鏈殘留」導致的幽靈故障。

補充:將 Gateway 日誌中握手失敗上游模型 429/5xx分標籤統計;若後者佔比高,應回到《provider 降級篇》,而不是繼續調 compose 網路。

若你已啟用《K8s 探活篇》裡的 HTTP 健康檢查,請把探針目標 URL與本文表 2 的 bind 策略對齊:探針若只打 loopback 而實際流量從另一網卡進入,會出現「探活全綠、用戶全紅」的錯位;這類問題在滾動發佈窗口最容易被誤報為「新版本壞了」。

為什麼「只在筆記本本機跑 Docker」難撐長期控制面

個人筆記本上的 Docker Desktop 睡眠、VPN 切換與本地代理常改變 localhost 解析與端口轉發行為;一旦要把 Gateway 交給團隊共用或交給 Agent 長期值守,就需要可重複的監聽策略、可審計的 compose 版本與穩定的宿主機網路邊界。純本地堆疊也難以同時提供多地區低延遲出口與物理機級隔離,與生產級自動化對「控制面總在可達位置」的要求相沖突。

對需要把 Gateway 放在可值班、可橫向擴展且網路邊界清晰的環境的團隊而言,將控制面落在專業雲 Mac / 多地區節點上,通常比依賴不穩定個人設備更符合節奏。MACCOME 在新加坡、日韓、香港與美東美西等提供 Mac Mini M4 / M4 Pro 物理節點與彈性租期,適合作為 OpenClaw 與 Apple 工具鏈共存的常駐執行平面;網路分診完成後,可在《SSH 與 VNC 指南》與幫助中心核對接入方式,再按公開價格與區域頁落單。

試點建議:先在獨佔測試機上把表 1、表 2 與命令塊跑通並歸檔日誌,再推廣到共享 compose 倉庫,避免「口口相傳的 network_mode」無法覆盤。

最後強調:任何把 Gateway 綁定到 0.0.0.0 以「先跑起來再說」的臨時方案,都應在變更單裡寫明回滾時間與暴露面評估;網路分診的目標不是無限擴大監聽範圍,而是讓「誰該看見控制面」與 compose 文件中的命名空間設計一致,這樣值班同學才能在五分鐘內向研發說明白根因。

常見問題

這篇和「Docker 生產與 Gateway 常駐」有什麼不同?

生產篇寫鏡像、卷、健康檢查與發佈;本篇只寫控制面可達性。裝後驗證入口見 幫助中心,並與《Docker 生產 Runbook》互鏈。

WSL2 上是否適用同一套表?

分診順序一致,但 localhost 轉發與 systemd 行為不同;請疊加《doctor 與 WSL2 排錯》中的症狀對照。

還要對比地區與租期去哪看?

若計劃把 Gateway 放在雲端 Mac,先用《多地區節點指南》與 租賃價格 對齊主鏈路,再定 SSH 出口與防火牆策略。