已用 Docker Compose 跑 OpenClaw的开发者里,最高频的挫败往往不是「镜像拉不下来」,而是Gateway 日志看似正常、浏览器或 CLI 却反复报连接被拒绝 / WebSocket 失败 / token 无效——其中大量案例根因在监听地址(bind)、端口发布、以及 CLI 与 Gateway 是否共享同一网络命名空间,而不是模型密钥本身。📌 本文给出六类可写进值班的网络症状、两张「进程已起 vs 路由可达」对照表、bind/防火墙/发布端口矩阵、可复制诊断命令、六步 Runbook 与三条应写进日志检索的硬口径;并与站内《Docker 与 Gateway 生产向 Runbook》《doctor 与装后排错》《K8s 探活与滚动更新》分工——生产篇管「怎么部署」,本篇管「包在跑但包与包、包与宿主机之间为什么互相看不见」。
OpenClaw 的控制面通常由 Gateway WebSocket/HTTP 与 CLI / Control UI 组成;Docker 场景下还会叠加 多个容器、自定义 bridge、以及 network_mode: service:... 等组合。若不做分层分诊,团队会在 .openclaw 与环境变量之间来回改,却不去看监听地址是否真的落在 CLI 可达的接口上。
127.0.0.1,宿主机通过 published port 访问时由代理层转发看似可通,但同 compose 内另一容器用服务名访问时却落到错误的协议视图。gateway:18789 走了 bridge DNS,而 Gateway 实际只向 service 侧暴露回环套接字——表现为间歇性「第一次能连、重启用后全挂」。18789 指到旧容器 IP,滚动升级后 iptables 规则残留,宿主机 curl 偶发成功、容器内始终失败。Upgrade 头在边缘被剥掉(与《Linux systemd + Tunnel》路径互补)。::1 或错误 AAAA,宿主机仅 IPv4 通——在部分云 Mac 或精简镜像上会被放大。把上述条目与《生产 Runbook》里的卷、镜像标签、健康检查放在同一变更单上:前者回答控制面是否可达,后者回答进程是否按预期版本在跑。
实务上建议在 compose 仓库里维护一页「网络拓扑说明」:画出 Gateway、CLI、可选的 edge 反代各自落在哪个 network、哪些端口由谁 publish、以及开发机与 CI 分别从哪里探测。没有这张图时,排障对话会反复落在「你是不是改了我本机的 hosts」这类不可审计路径上。再补充一点:Docker 的 DNS 解析在自定义网络与默认 bridge 上行为并不相同,服务名解析失败时不要先怀疑 OpenClaw 本身,先用 docker compose exec 进容器跑 getent hosts 或 nslookup 确认名字是否落在预期 IP。
第一步永远用官方 CLI 做存活与版本对齐(见《doctor 篇》),再进入下表。不要在未确认进程监听之前就改 token。
| 观测 | 更可能类别 | 优先动作 | 常见误操作 |
|---|---|---|---|
docker ps 无 Gateway 容器或持续重启 | 未起 / CrashLoop | 看 docker 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 选项 |
gateway.bind、端口发布与防火墙—对照矩阵(Docker 专用读法)下列读法与官方文档中「bind 取 loopback / lan / tailnet / auto 等枚举」一致;Compose 里还要把谁负责 publish写清。
| 目标 | 典型 bind / 环境变量思路 | Compose 注意点 | 安全边界 |
|---|---|---|---|
| 仅本机开发机自测 | 偏向 loopback;由宿主机浏览器访问 published port | 127.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 | 分离 gateway 与 edge 网络;校验 WebSocket 透传 | 禁止把管理口直接对公网裸暴露 |
# 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'
注意:社区 issue 中常见「CLI 无法连接 Gateway」与 compose 未让 CLI 与 Gateway 共享网络命名空间相关:修改前先在测试 compose 上验证第三节命令块,再合并到生产文件。
下列步骤假设你已能拉取镜像;若尚未完成安装入口,请先读《三平台安装与平台选择》。
wget/curl。Upgrade 与路径重写,再回到 Gateway 日志对照(与 Tunnel 篇分工)。下列字段把「偶发连不上」变成可对比回归的信号,并与《K8s 探活篇》中的 HTTP 探针字段兼容(迁移到编排时可直接映射)。
ss 输出的 Local Address:Port + 进程名 + compose 服务名;任一变更必须出现在变更单。docker port 与实际 iptables NAT 规则是否在滚动后仍指向当前任务 IP;2026 年常见「升级后旧链残留」导致的幽灵故障。补充:将 Gateway 日志中握手失败与上游模型 429/5xx分标签统计;若后者占比高,应回到《provider 降级篇》,而不是继续调 compose 网络。
若你已启用《K8s 探活篇》里的 HTTP 健康检查,请把探针目标 URL与本文表 2 的 bind 策略对齐:探针若只打 loopback 而实际流量从另一网卡进入,会出现「探活全绿、用户全红」的错位;这类问题在滚动发布窗口最容易被误报为「新版本坏了」。
个人笔记本上的 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 排错》中的症状对照。