把 AI 开发工具链装进可复用的 Docker 沙箱
作者以 AI Agent 将 TeX Live 安装到临时目录、重启后需重装的问题为切入点,介绍用 Docker Sandboxes 管理开发工具链。流程涵盖创建 microVM 沙箱、安装依赖、保存快照,以及通过 Dockerfile 重建和共享环境。
AI 深度解读
AI agent 把 TeX Live 装进 /tmp,当时能编译,重启后却得重新安装。作者借这个小事故,把写书所需的 Node.js、Pandoc 和 XeLaTeX 搬进 Docker Sandboxes:宿主机少装工具,开发环境可以保存、重建和复用。
这篇真正有用的,是走通了从手动安装、保存快照到 Dockerfile 管理环境的完整路径,也交代了网络权限、目录挂载和版本差异。对需要让 AI agent 执行构建任务的程序员,这些细节比「用了沙箱就安全」更值得看。
沙箱隔离了什么,又留下了什么
Docker Sandboxes 使用微型虚拟机(microVM)隔离本地工作负载,由 sbx CLI 管理。作者在 2026 年 11 月 9 日使用 v0.51.0 验证依赖安装、快照复用、Dockerfile 构建及导入导出,11 月 10 日又在 Apple silicon Mac 上重复了流程。
测试不只检查命令是否存在。作者运行了 Node.js → Pandoc → XeLaTeX 的 PDF 冒烟测试,还在 codex/docker-sandboxes-in-action 分支验证 npm run book:sbx:pdf,两种环境都生成了 42 页 PDF。

运行前需要确认平台条件:Linux 为 Ubuntu 24.04 或更新版本,支持 64 位 Intel、AMD 或 Arm,需要 KVM,用户须加入 kvm 组;Mac 为 Apple silicon、macOS 14 或更新版本;Windows 为 64 位 Intel 或 AMD 的 Windows 11,并启用 Windows Hypervisor Platform。
sbx 本身不依赖宿主机 Docker Engine,但后面的 docker build 和 docker image save 需要 Docker Engine 或 Docker Desktop。先用 sbx --version 核对版本,再执行 sbx login。
创建环境的入口是 sbx create --name sbx-book shell .,随后用 sbx run --name sbx-book 进入。v0.51.0 的内置 shell kit 使用 Debian 13,带 Git,不带本例需要的 Node.js 和 npm。
microVM 隔离宿主系统,但不会保护你主动共享进去的文件。
末尾的 . 会把当前目录以读写方式挂载进去。PDF 能直接出现在宿主机,agent 也能直接修改、删除项目文件。需要先审查改动时,可以使用 --clone,让沙箱操作私有工作副本。
为什么先限制网络,再安装依赖
作者先执行 sbx policy init deny-all,把网络策略设为默认拒绝,再按需开放地址。这个顺序适合后续运行 AI agent:先确定它能访问哪里,再让它执行任务。
但初始化不是清空已有规则。旧的全局允许规则仍然生效;想重新开始,需要先执行 sbx policy reset。作者在 Mac 上就遇到旧策略已允许 **.debian.org 和 dhi.io,导致 apt update 直接成功的情况。可以用 sbx policy ls 和 sbx policy check network github.com:443 检查。
允许名单要看沙箱内部的软件源,不能照搬宿主机配置。作者的宿主机是 Ubuntu,内置环境却是 Debian。实测所需地址为 deb.debian.org 和 dhi.io,在宿主机另开终端执行:
sbx policy allow network --sandbox sbx-book 'deb.debian.org,dhi.io'
其他镜像可能使用 security.debian.org 或 Ubuntu 镜像站,需要以实际配置为准。首次拉取 shell kit 时,宿主机也需要访问镜像仓库。
这里有个容易误判的错误:仓库被拦截时,apt update 可能同时报告 403 和「repository is not signed」。应该修正网络规则,不要关闭签名校验。
安装也并非没有副作用。作者这次下载约 820 MB,新增占用约 2.5 GB,还把 kit 中的 Python 3.14 软件包替换成 Debian Python 3.13。项目依赖特定 Python 版本时,安装确认列表必须看。
快照方便复用,Dockerfile 才能解释环境怎么来的
装好工具后,停止再启动同一个沙箱,依赖仍然保留。要给其他沙箱复用,则先执行 sbx stop sbx-book,再执行 sbx template save sbx-book sbx-book:texlive-v1。
这类似 docker commit:保存当前文件系统状态。创建新环境时指定 --template sbx-book:texlive-v1 --pull never,就能复用本地模板,不必重新下载 TeX Live。对这种快照,--pull never 已是默认行为,显式写出方便理解。
问题也一样:快照记录结果,却没有记录安装过程。需要审查、升级或交给同事维护时,Dockerfile 更合适。
下面这份定义把书籍构建依赖写进环境,安装完成后切回普通用户:
FROM docker.io/sbx/shell-image:latest
USER root
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
nodejs \
npm \
pandoc \
latexmk \
texlive-xetex \
texlive-latex-extra \
texlive-fonts-recommended \
texlive-fonts-extra \
lmodern \
fonts-lmodern \
fonts-dejavu \
fontconfig && \
rm -rf /var/lib/apt/lists/*
USER agent
重点看第一行和最后一行:基础镜像必须兼容 Docker Sandboxes,不能随便换成普通 Ubuntu;运行时回到 agent 用户。旧的 docker/sandbox-templates:shell 已不再更新。
这条路径与内置 kit 还有版本差别。作者测试的独立 sbx/shell-image:latest 使用 Ubuntu 26.04,安装得到 Pandoc 3.7.0.2、Node.js 22.22.1;Debian 快照则是 Pandoc 3.1.11.1、Node.js 20.19.2。
同一条构建命令能通过,不代表两套环境的依赖完全相同。
用 docker build -t sbx-book:texlive-v2 ./sbx-template 构建后,还不能直接交给 sbx。两者不共享镜像存储,需要导出再导入:
docker image save \
sbx-book:texlive-v2 \
-o sbx-book-texlive-v2.tar
sbx template load sbx-book-texlive-v2.tar
要注意第二条命令,它才把镜像交给 Docker Sandboxes。随后创建 sbx-book-built,指定模板和 --pull never,即可再次运行 npm run book:sbx:pdf。
Dockerfile 也不自动保证严格复现。latest 和未锁定的软件包会变化;要求更严时,需要固定基础镜像 digest、软件包版本,必要时使用软件仓库快照。
我的判断
我认同把体积大、低频使用的构建工具链放进独立环境。作者已经证明这套流程能完成实际任务,也验证了两种系统环境下的路径。不过,原文没有提供与普通 Docker 容器、Dev Containers 的启动速度、内存占用或维护成本对照,不能据此认定 Sandboxes 是所有项目的更优选择。
收益更明确的场景,是既要准备开发工具,又要约束 AI agent 的运行环境。若还需要声明网络访问、凭据请求和 agent 指令,可以进一步考虑 Kit v3:用 YAML 描述符配合 Dockerfile,workload kit 提供基础环境和启动命令,mixin kit 添加工具或行为。编写好 kit 后,sbx run --name my-project ./my-kit 可以自动构建,省去手动导入导出。
代价也很具体。作者在 Mac 上的 Dockerfile 镜像占用约 7 GB,导出的 tar 为 1.9 GB,texlive-fonts-extra 是大头。它解决的是重复安装和宿主机依赖管理,不是让工具链变轻。
此外,模板不是备份:不包含挂载的工作目录,也不携带网络策略;快照还可能保存凭据。团队采用前,需要把环境定义、项目文件和权限分别管理。
能拿来做什么
- 如果 Node.js 项目还调用 Pandoc、LaTeX 等系统工具,可以先放进 shell 沙箱跑通真实构建,再把成功的安装过程整理成 Dockerfile,并记录验收命令。
- 让 AI agent 执行任务前,先检查目录是否直接读写挂载;需要审查结果的 Git 项目使用
--clone,网络则从deny-all开始逐项开放。 - 复用模板时,同时检查 Node.js、Pandoc 和字体是否可用,再跑项目构建。作者使用了
fc-match "Latin Modern Roman"和kpsewhich yfrak.tfm,避免只确认编译器存在却漏掉字体。 - 团队维护环境时,把 Dockerfile 纳入版本控制;只有在还要统一 agent 权限、凭据请求和运行指令时,再评估 Kits。