
TL;DR
在 Mac 上装好 Docker Sandboxes,把 Coding Agent 跑进一台可以随手删掉的微虚拟机。它自己的内核、文件系统、网络、Docker Engine,宿主机都碰不到------但你主动挂进去的项目目录是例外,Agent 在里面读写和你本人权限一样,不受额外限制。
安装到跑通 OpenCode,最短路径不到十分钟;真正费事的是模型登录:sandbox 不继承宿主机账号,SuperGrok 这类订阅还要单独 /connect 并放行网络策略。装完能人机协作改同一棵树,还不到无人值守的程度。
引言
给 Coding Agent 选运行环境时,「容器 vs 微虚拟机」不是选择题,是真问题。
Agent 要自己装依赖、跑测试、起 Compose,才算真的在干活。这些事权限不低。常见做法是把宿主机的 Docker socket 挂进容器,等于把整台机器的 Docker 交给它------风险出在共享宿主机内核和宿主机 Docker 上。
Docker Sandboxes 换了个方案:不共享内核和 Docker,而是给每个任务一个可以删掉的微虚拟机。项目还在你的 Mac 上,宿主机的 Docker 它碰不到。
下面只做一件事:在 Apple Silicon 的 Mac 上,从安装走到第一次跑起来。环境是 M1 Pro、sbx v0.38.0、OpenCode。宿主机上的 Docker 是 OrbStack。不是全 Agent 评测,也不讲隔离机制的全景。
能删的虚拟机,删不掉的工作区
一个 sandbox 对应一台微虚拟机,不是一次对话。Agent 退出后环境还在,再连上去,装过的包和拉过的镜像都在。只有 sbx rm 才拆掉。
里面有四样东西:
- 自己的 Linux kernel,不是和 Mac 共用一个
- 自己的文件系统,宿主机上的目录默认进不去
- 自己的网络,出站走策略,宿主机 localhost 不是它的 localhost
- 自己的 Docker Engine。在里面
docker ps,看到的不是 OrbStack
项目目录是挂进去的,路径和 Mac 上一样。Agent 改的文件,你这边立刻看得到。这是协作需要的,也是边界:工作区里的 .env、.git 都能被 Agent 直接读到,没有额外的权限限制去挡它。
和「容器里再跑 Agent、再把 docker.sock 挂进去」的差别就在这里。后者共享的是宿主机内核和宿主机 Docker;前者把这两样留在微虚拟机里。
具体到 Agent 这边,Docker 给这条链路预置了 Claude Code、Codex、OpenCode 等几个 Agent,加上一个没有预装 Agent 的 shell。本文只测 OpenCode------Kimaki(我自己接的 Discord + OpenCode 方案)和 omp(Pi 的一个功能拉满的独立 fork,不是 Pi 的新版本)都是独立于 Docker Sandboxes 官方支持列表之外的工具,能不能接进来是另一个问题,不在这篇的范围内。
装得快,连得慢
官方名单里的 Mac 只有 Apple Silicon,系统至少 Sonoma 14。Homebrew cask 也写死 arm64,Intel Mac 现在装不上。这是产品支持范围,不是 Intel 机器不能做虚拟化。Docker Desktop 不是前置条件------sbx 自己拉微虚拟机,也不依赖我已经在用的 OrbStack。
bash
brew trust docker/tap
brew install docker/tap/sbx
sbx login
sbx login 走浏览器里的 Docker 账号。装完 CLI 不会自动拉起后台进程。我这边要先常驻 daemon,再初始化网络策略,否则后面执行 sbx run 之类的命令会因为策略未初始化而报错:
bash
sbx daemon start
sbx policy init balanced
daemon start 前台阻塞,适合丢给 launchd 一类的进程管理,不要挂在你正用的那个终端里不管。
daemon 起来之后,再看网络策略。官方把出站预设分成三档:Open 全开,Locked Down 全拦,Balanced 是居中那档------默认拒绝,只放行模型 API、包管理器、代码托管和 Registry 这类常见开发站点。文档里也可以在第一次 sbx run 时交互选;两条路选一条即可。
然后进项目目录:
bash
cd ~/your-project
sbx run opencode
第一次会拉 OpenCode 的模板镜像,要等一会儿。起来的是 TUI,不是 Claude Code 那种自动跳过确认的会话。
模型不会跟过来。宿主机上已经登录的 OpenCode,sandbox 里看不到。
我用的是 xAI 的 SuperGrok 订阅,不是 console.x.ai 的 API Key。sbx secret set xai 只支持写入 API Key,不支持这种订阅制 OAuth 凭证,所以要在 TUI 里 /connect,选 xAI 的 Headless OAuth。balanced 默认不放行 xAI 的登录域名,device code 出不来,要先加规则:
bash
sbx policy allow network "*.x.ai:443,api.x.ai:443,auth.x.ai:443,accounts.x.ai:443"
如果你走 Anthropic、OpenAI 这类 API Key,用 sbx secret set <provider> 即可,一般不必改策略。
连上之后就可以丢一个真任务进去,比如跑测试、补缺的函数。文件改动会出现在你的工作区里,用平时的 git diff 看就行。
停掉但留下环境用 sbx stop,下次 sbx run --name <sandbox> 再连。不要了再 sbx rm。需要进编辑器时,先 sbx setup ssh,然后 ssh <name>.sbx;VS Code 的 Remote-SSH 也能连这个主机名。
省的是确认,不是配置
工作区还在 Mac 上,OrbStack/Docker Desktop 还是你的 Docker,Agent 用它自己那一套。装依赖、跑测试、起容器,都可以在里面做,不必把宿主机的 Docker socket 交出去。
这条最短路径里,真正费事的不是拉镜像,是模型怎么进去。sandbox 不继承本机 OpenCode 登录;我用 SuperGrok,还要自己 /connect,并给 balanced 补上 xAI 的域名。YOLO 省掉的是一条条点确认,不是这些配置。
眼下这条路适合人在旁边、和 Agent 改同一棵树。装完不能当无人值守,Kimaki 和 omp 也开箱接不上。工作区挂进去之后,.env 对 Agent 是可见的:隔离挡的是工作区外面,不是工作区里面。工作区是不是必须直接读写、能不能换成给 Agent 一份隔离副本,这道边界具体打在哪,后面再写。