你已经能用 Docker / Compose 跑 OpenClaw Gateway,但一打开 Agent 沙箱就出现:容器起不来、工作区只读/不可写、沙箱里明明缺命令、一构建就 OOM 退出 137。本文把 2026 年主流落地路径压成可执行顺序:关→开→验→排障,用配置键位、卷权限与 `docker.user` 对齐、镜像构建与 OOM 分诊表和站内已有「Docker 安装/卷权限/doctor」类文章明确分工。读完你应能判断:是镜像问题、挂载 UID 问题、还是资源上限与日志关键字问题。
根因往往不在「OpenClaw 装坏了」,而在进程边界:
brew install 的东西不会自动出现在沙箱的 PATH,除非进镜像或额外挂载/层。501:20、容器里进程是 1000:1000 跑,常出现只读失败或写拒绝,日志里以 Permission denied 或 EROFS 呈现。| 模式 | 适合什么 | 你付出的成本 | 常见误判 |
|---|---|---|---|
| Docker 沙箱 | 要对不可信命令/脚本做硬隔离,复现「干净环境」 | 镜像体积、拉取/构建、UID/GID/卷要对齐 | 以为宿主机工具自动继承 |
| SSH / 远端 shell | 在你信任的远程 Mac上直接跑(例如独占构建机),需要完整工具链 | 暴露面与账户模型变大 | 把本机当沙箱、忘记审计 |
| 无沙箱 / 全本地 | 内网、低危、可快速排障 | 任一代码被模型执行时风险高 | 在 CI/生产也长期关闭 |
概念上分两层:用哪个沙箱实现(Docker 镜像/运行时)和镜像从哪来。官方仓库通常提供 scripts/sandbox-setup.sh(名称以你本地克隆版本为准)来预构建/拉取作为宿主机上 docker CLI 能识别的镜像。配置里 agents.defaults.sandbox.docker.image 指向要运行会话的那个镜像;两者不一致时,典型症状是「Gateway 认为沙箱已启用,但 docker run 报 manifest not found 或 pull access denied」。
和已有文章怎么分工? 若你卡在 OPENCLAW_IMAGE 或 Control UI 入口,先按 官方 Docker 一键与 GHCR 镜像;若你卡在数据卷、权限、持久化与 Skills 路径,对照 Docker 卷与权限检查表。本篇只盯 沙箱子系统 + OOM/137。
OPENCLAW_HOME 挂载:按症状对齐,而不是乱 `chmod 777`推荐顺序:
docker.user 为 与卷可写性一致的 UID:GID(以文档键名为准,若你版本用嵌套表结构则对应到 sandbox.docker 下);chown,优先调整挂载到容器内的子目录,而不是放开整个磁盘。对 Linux 与远程 Mac 的细微差别是:命名卷、绑定挂载、SELinux 标签(在部分发行版上)会放大「在 compose 里看着对、进容器就错」的现象。此时要在 Gateway/沙箱容器的启动日志中抓首条 I/O 错误行,而不是在模型对话里试运气。
PATH 的目录**中?docker exec 到沙箱里跑 command -v 比口述可靠。~/.cache 之类路径才能跑?若是,要评估把缓存放进镜像/公共层,而不是从宿主随意穿越。HTTP(S)_PROXY?网络失败常被误报成 command not found。exit 137:在 Docker 里如何读「被杀」与「不够内存」137 = 128 + 9 (SIGKILL) 在实践里常和 OOM killer 相关,但你也可能看到 人为 docker kill 或 cgroup 内存限制 触顶。分诊上至少做三件事:看 构建阶段是 docker build 还是 docker run;在引擎侧看 concurrent build 是否让 Docker Desktop / VM 内存打满;对远程 Mac/专用机则看系统真实可用内存与 swap 压力,而不是只盯单容器 limits。另有一类易混信号是退出码 1 或 2却伴随大量 Cannot allocate memory 文本,也要并入「内存/磁盘临时空间」同一张表,避免在模型侧反复调参却不动容器。
对「构建时 OOM」的通用减负顺序:关并行层(--parallel 等)、用多阶段构建减少编译峰、提高 Docker VM 分配、换带更多内存的 独占远程 Mac 档位 作为稳定基座。这与「在笔记本上开多个 IDE + 本地大模型 + Docker」的偶然成功不是一类事件。若团队已上共享存储,额外关注inode 与元数据小文件爆发导致的「像 OOM 一样卡死」现象,必要时分卷或改清理策略。
sandbox-setup 构建或拉取镜像,记录**镜像名与 ID** 与配置一致。docker.user 与挂载做 A/B:只改一个变量、保留 diff,避免同时改三处后无法回滚。{
"agents": {
"defaults": {
"sandbox": { "mode": "docker" },
"docker": { "user": "1000:1000" }
}
}
}
// 实际项目可能为嵌套在 sandbox.docker 下,请先 openclaw doctor / 对照官方文档
docker events 或引擎日志、宿主机 memory pressure,避免把业务 OOM 与 docker build 并行 OOM 混为同一类事故。chown -R 1000:1000 单个项目目录 与「动整个家目录」风险不同,变更要有工单与回滚点。pip 索引、以及无持久层时的重复下载,会把「能跑通一次」和「能跑通一百次」的成本拉开,应在容量评审里给首启时间一个数字。这类替代拓扑通常输在内存与 I/O 的同时峰值与可重复的环境边界上:你昨天能构建,是侥幸没有并发;而生产 Agent 在高峰会稳定触发 137 与写放大。对需要7×24 Gateway + 沙箱的团队,更可控的组合是 独占的 Apple Silicon 云主机、清晰磁盘与日志策略、可预期的租期。在这种前提下,MACCOME 的远程 Mac 云算力更适合作为 OpenClaw 的常驻基座——你减少的是与随机本地环境搏斗的时间,把精力放回工具链与产品交付。
常见问题
沙箱里找不到宿主机已安装的命令怎么办?
把**工具安装进沙箱镜像**或调整镜像层;或按策略挂载额外目录并更新 PATH。这与 MCP/Skills 校验里「工具在 Gateway 层可见性」的排法类似,但发生在容器边界内。
看到 exit 137 就一定是 OOM 吗?
不必然。要区分 cgroup 限流、系统 OOM、与人为 kill;至少抓一段同一时刻的引擎与系统内存曲线再下结论。日常入口也可先看 官方 doctor/无回复分诊 的日志读法。
开沙箱和买更大内存的 Mac 云主机,哪个先?
先证明是隔离需求还是资源不足:用最小复现压一次。若 137 在提高 Docker 分配或更大内存后消失,是资源;若你始终要跑不可信代码,是沙箱+治理。价目可对照 Mac 云主机租赁 的公开档。