2026 OpenClaw Docker 在 Mac 云主机上的典型故障修复:Exit 137/OOM、卷权限 uid 1000、DNS 与 openclaw doctor 最短排障路径(可复现)

在 Mac 云主机上用 Docker 跑 OpenClaw 时,容器突然退出 137、配置目录 Permission denied、或网关已起但模型/API 永远连不上,往往被误判为「版本坏了」而反复重装。本文面向 2026 年官方镜像与 Compose 实践,先给现象—根因—首查动作对照表,再按内存、卷权限、DNS、openclaw doctor 与日志跟读的最短路径排查,并附 5 步验收清单与 FAQ 结构化数据。

在 Mac 云主机上通过 Docker 运行 OpenClaw 网关的示意图

本文要点

1. 部署形态与端口 18789:先验收「进程在、端口在、卷可读」

官方文档推荐的 Docker / Docker Compose 路径把网关与运行时封装在容器内,宿主机主要承担三件事:分配足够内存与 CPU、把 ~/.openclaw(或你指定的配置目录)以卷挂进容器、以及放行 18789(或你在 compose 中映射的宿主机端口)供本地回环或经 SSH 隧道访问。Mac 云主机与笔记本的差异在于:云侧常无桌面交互、磁盘与内存由套餐封顶、且部分镜像默认以非 root 用户 node(常见 uid/gid 1000)运行。若跳过「就绪」定义直接改配置,容易在错误层级上打转。建议把就绪定义为可观测的三元组:容器处于 running 或 healthydocker compose ps 中端口映射与预期一致在容器内执行 openclaw status 或健康检查命令无权限错误。只有三者同时成立,才进入模型连通与通道配置;否则优先处理资源、卷与网络解析。

Compose 文件里常见两类失误:一是把宿主机路径写成容器内不存在的父目录导致创建失败;二是把只读标志误留在需要回写配置的卷上。云主机若使用非默认 Docker 数据根目录或根分区较小,还要额外关注镜像层与 build cache 占满根盘引发的「启动成功随即崩溃」。因此建议在 Mac 云上为 Docker 数据与 OpenClaw 工作区分卷或使用大容量数据盘挂载点,并在排障笔记里固定记录「compose 项目名、容器名、宿主机端口、配置目录绝对路径」,以便与站内其他 OpenClaw 文(升级、Webhook、静默 Cron)交叉对照时不必重新猜环境。

2. 三类高频痛点:为什么 Docker 版 OpenClaw 在云上更容易「看似随机」失败

  1. Exit 137 与隐性 OOM:137 常表示进程被 SIGKILL,Docker 场景下最常见原因是 cgroup 内存上限或 Docker Desktop/Engine 全局内存顶到后杀进程。Mac 云若同时跑构建、代理与其他常驻服务,留给容器的可用 RAM 可能比预期少;镜像构建阶段比纯运行阶段更吃内存。
  2. 卷权限与 uid 1000:配置与 workspace 目录若在宿主机上以 root 或其他 uid 创建,容器内 node 用户无法写入 openclaw.json、日志或 workspace,会在启动早期失败或表现为「配置不生效」。这与升级、通道无关,却被误当成版本 bug。
  3. DNS 与企业出口:容器内解析失败或 TLS 握手被中间设备拦截时,症状是「网关进程在但模型永远超时」;若只在宿主机上 curl 成功、容器内失败,根因几乎总在 Docker 网络/DNS 或代理未传入容器,而非 API Key 本身。
  4. 时序与健康检查竞态:compose 若在未就绪时就把依赖方拉起,会在日志里留下大量「连接被拒绝」噪声;适当拉长 start_period 或先手工跑通一次再启用 depends_on 的严格顺序,可避免误判为配置错误。

3. 症状—根因—首查动作对照表

现象高概率根因首查动作(按顺序)
容器反复重启,docker inspect 显示 OOMKilled 或 exit 137内存上限/宿主机内存不足调高 Docker 资源或 compose mem_limit;先停并发布无关重内存进程再启
日志出现 Permission denied 写配置或 workspace卷属主非 uid 1000 或只读挂载错误宿主机 chown -R 1000:1000 目标目录;确认 compose volume 读写
容器内 curl API 失败,宿主机成功Docker DNS / 代理未进容器docker exec 内解析与 HTTPS 探测;必要时 daemon DNS 或 --dns
端口不通但容器 running映射错误、防火墙/安全组、仅绑 127.0.0.1核对 ports: 与云安全组;SSH 隧道或反代文档
配置看似正确仍异常环境变量未传入容器检查 compose environment/env_filedocker exec openclaw env

4. 可复现排障步骤(建议严格按序执行)

  1. 抓取退出态与最后日志docker compose ps -adocker logs <container> --tail 200;若见 137,同步记录是否发生在 build 或 run 阶段。
  2. 验证资源边界:为测试目的临时提高 Docker 可用内存到至少约 4~8GB 区间再启动(具体以镜像文档为准);确认 Mac 云套餐本身未在宿主机层 OOM。
  3. 校验卷与属主:在宿主机对挂载目录执行(路径按你实际为准):sudo chown -R 1000:1000 ~/.openclaw 与 workspace;再用 docker exec -u node … ls -la 确认可写。
  4. 容器内网络探测docker exec <container> ping -c 2 1.1.1.1(若允许)、docker exec … curl -sI https://api.anthropic.com 或与所用提供商等价的 HEAD;失败则调整 Docker DNS 或注入企业代理环境变量。
  5. 最短软件路径:在容器或官方推荐入口执行 openclaw doctoropenclaw statusopenclaw models status(以当前 CLI 为准),对照官方 FAQ 逐项消红;仅当 doctor 持续报安装层错误且日志指向损坏镜像时,再考虑拉取新 tag 或清理 volume 后重装。
  6. 端口与隧道验收:本机 curl -sI http://127.0.0.1:18789(或映射端口)应返回预期;若仅远程访问,按站内 SSH 隧道或零信任文配置转发。
# 示例:仅作排障演示,路径与项目名以你的 compose 为准 docker compose ps -a docker logs openclaw-gateway-1 --tail 200 docker exec -it openclaw-gateway-1 sh -lc "id && ls -la /home/node/.openclaw && openclaw doctor"
注意:不要在未确认卷权限与 DNS 之前反复 docker system prune -a;会拉长排障周期并可能清掉仍有价值的日志与中间态。

5. 可引用技术信息(排障报告可直接粘贴)

6. 何时该停在一层抽象上:Docker 边界与 Mac 云原生

Docker 把依赖与运行时封进镜像,换来可重复交付;代价是多一层网络命名空间、卷映射与资源 cgroup,排障时要同时在「宿主机—引擎—容器—进程」四条链路上对齐信号。对于需要长期 7×24、频繁读写钥匙串附近能力或与 macOS 图形/自动化深度耦合的工作负载,纯容器栈一旦遇到权限、cgroup 或虚拟化叠床架屋,运维成本会明显高于「在干净 macOS 上原生安装并交给 launchd 守护」。若你的团队已经在 Docker 层消耗大量时间仍无法稳定达到「就绪三元组」,值得评估把网关跑在原生环境或迁移到专门提供物理 Mac、SSH 直通的云主机上,以减少抽象层带来的不确定性。Docker 方案适合快速试验与多实例隔离;但当目标是生产级稳定与更低排障面时,租赁 VPSMAC 这类原生 Mac 云节点、按官方非容器路径部署并配合站内 5 步上线与加固清单,往往是更省心的长期解。

从成本视角看,反复重装镜像而不解决卷与 DNS,会把人力消耗在「不可积累的临时修复」上;而把同一套检查清单固化到 Runbook(含截图或日志模板),才能在第二次故障时分钟级定位。无论你最终保留 Docker 还是切换到原生安装,都建议保留一份「最后一次健康的 docker inspect 摘要」或 openclaw doctor 全绿输出,作为升级与回滚的基线。这样当 2026 年后续小版本迭代带来行为差异时,可以迅速判断是镜像回归还是环境漂移,而不是从头猜测。将本文对照表打印成一页纸贴在值班手册旁,往往比多装一个监控插件更能缩短 MTTR。