
Nx 仓库审查沙箱一次性初始化setup-review-sandbox 完整实操指南【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx在 nrwl/nx本仓库中任何未发布的 PR 代码都被视为不可信代码绝不能在你的宿主机上执行安装脚本、构建或复现命令。为此仓库内置了一套基于 Docker 的隔离审查沙箱体系而setup-review-sandbox技能负责一次性把它的全部前置条件安装到位Docker 引擎、隔离运行时Linux 上的 gVisor / macOS 上的 Docker VM、健康的容器网络以及内置完整工具链的nx-review-sandbox镜像。读完本文你将掌握这套沙箱的完整初始化流程、各步骤的故障排查方法、工具链镜像的构建原理以及磁盘回收与安全边界管理的最佳实践。一、背景沙箱在整个审查工作流中的位置在动手指南之前先明确这套沙箱服务谁、解决什么问题。仓库把不可信代码的边界定义为执行而非阅读宿主可以自由读取 PR/Issue 的公开信息但 PR 作者写的代码postinstall 脚本、构建、测试、复现命令只能在隔离容器内运行。这个模型由三个组件共同落地reproduce-issue 技能把某个 issue 的复现过程完全搬进隔离容器内执行宿主上零落地reproduce-verifier AgentPR 审查时验证这个 PR 是否真的修好了它声称修复的 bug其 Level 2PR 构建模式依赖nx-review-sandbox镜像review-pr 技能深度 PR 审查的编排者其 pre-flight 阶段会无条件调用构建脚本。setup-review-sandbox就是这三者的地基。当用户说出set up the review sandbox、install the sandbox prereqs、build the sandbox image或某个 reproduce-issue 预检报告某组件 MISSING 时就该运行它。该技能的设计哲学有三点值得先记住幂等Idempotent每一步都先检查、仅在必要时才动手重复运行只是验证 修复sudo 交接需要 root 的操作安装 Docker、注册 runsc、modprobe 等不会以非交互方式强行 sudo而是打印给用户、由用户在自己的终端里执行分平台Linux 与 macOS 的沙箱边界来源不同第一步永远是uname -s——Linux 走 gVisor 路线macOSDarwin走 Docker VM 路线。二、第一步Docker 引擎先确认 Docker 是否可用一条命令即可docker info /dev/null 21 echo docker OK || echo docker MISSINGMISSING 且是 Linux安装 Docker Engine 后执行sudo systemctl enable --now docker让服务开机自启并把当前用户加入docker组sudo usermod -aG docker $USER然后重新登录使组生效MISSING 且是 macOSbrew install colima docker后colima start或直接安装 Docker Desktop。注意 macOS 上 Colima 不是可选配菜而是必需组件它提供的 Linux VM 本身就是后面第 2 节的沙箱边界。三、第二步隔离运行时3.1 Linux —— gVisorrunscLinux 上沙箱边界来自 gVisor它是运行在 Docker 之下的用户态内核。先检查它是否已注册为 Docker 运行时docker info --format {{range $k,$v : .Runtimes}}{{$k}} {{end}} | grep -q runsc echo runsc OK || echo runsc MISSING如果 MISSING把下面整段交给用户在自己的终端执行需要 sudo若用户 shell 是 fish注意其退出码变量是$statussudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl gnupg curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main | sudo tee /etc/apt/sources.list.d/gvisor.list sudo apt-get update sudo apt-get install -y runsc sudo runsc install # 把 runsc 注册为 Docker 运行时 sudo systemctl restart docker执行完重新跑上面的运行时检查命令确认。3.2 macOS —— Docker VM 本身就是沙箱macOS 上没有runsc。因为容器实际跑在 Colima/Docker Desktop 提供的 Linux VM 里宿主内核与容器内核天然隔离。只需确认 VM 在线docker info /dev/null 21 echo docker VM OK || echo start it: colima start3.3 从源码看为什么必须是 gVisor这一设计并非随意选择。沙箱 CLI .claude/tools/sandbox 中定义了三档执行权限none screened full并明确隔离失败则关闭fail closed在 Linux 上如果runsc未注册sandbox start会直接拒绝启动而不是悄悄降级到普通的 runc 容器。其理由是历史教训——无隔离却报告成功是每一层之上都看不见的失效模式一个未设置的运行时变量会展开为空与 macOS 的正确值在字节上完全相同肉眼根本无法区分。这正是本技能第 2 节必须把 gVisor 装到位的原因它是 Linux 上唯一被认可的隔离边界。四、第三步容器网络健康检查专治veth一类故障网络检查是沙箱就绪验证中最容易踩坑的一环两条命令一起跑docker run --rm --network none alpine true echo sandbox OK docker run --rm alpine true echo networking OK || echo networking BROKEN第一条验证容器本身能否拉起无网络模式第二条验证容器网络是否可用。如果第一条通过而第二条报veth ... operation not supported说明 Docker 的虚拟网卡模块没被加载修复命令是sudo modprobe veth如果modprobe报 BTF / 版本不匹配failed to validate module [veth] BTF含义是当前运行的内核与磁盘上的内核模块不再对应——通常是一次内核升级发生在系统启动之后。此时重启重启后模块会自动加载如果想持久化执行echo veth | sudo tee /etc/modules-load.d/veth.conf。值得一提的是reproduce-issue 技能 的 Preflight 第 2 步也复用了这对检查A/B 两条命令并明确指出这条检查本可以在当年 veth 故障发生时立刻定位问题。可见网络检查不是形式主义而是整个预检链条里真实拦截过故障的关卡。五、第四步工具链镜像nx-review-sandbox本技能的核心5.1 何时才需要它需要澄清一个常见误区镜像仅用于在沙箱内构建未发布的 PR 的 nx对应 reproduce-verifier 的 Level 2 / reproduce-issue 的 PR 构建模式nx-build。如果只是针对已发布版本做复现根本不需要这个镜像——那条路径只需要第 13 节加一个公共node镜像即可。5.2 构建命令无条件执行不做存在性检查bash tools/review-sandbox/build-image.sh不要用镜像是否存在来短路这条命令。这是本技能特别强调的一点任何旧版本构建出来的镜像都能通过存在性检查于是某个缺失的能力会一直隐形直到某次审查莫名变慢才暴露——历史上就发生过一次镜像早于 pnpm store 预热功能构建导致两个星期内每次审查都要多花约 25 分钟下载依赖包。Docker 的层缓存已经回答了是否需要重建这个问题什么都没变 → 约0.6 秒全部命中缓存Dockerfile / mise.toml 变了 → 从变更的指令处开始重建pnpm-lock.yaml 变了 → 重跑pnpm fetch让预热的 store 始终匹配审查实际安装的 lockfile。构建脚本 tools/review-sandbox/build-image.sh 的实现还说明了两个工程细节用镜像 ID 而非日志判断是否重建脚本用docker images -q在构建前后各取一次镜像 ID精确比对比对日志里有没有 CACHED 字样是猜ID 是事实然后打印一行自解释的结果sandbox image up to date或sandbox image rebuilt (before - after)并发安全review-pr最多会同时开 5 个并行面板调用它BuildKit 会对相同的并发构建去重实测一个 20 秒的步骤在 5 路并发下只真正执行了一次总耗时约 21 秒而非 100 秒所以脚本自身无需加锁。5.3 最小构建上下文只送 5 个文件脚本构建时绝不以仓库根目录作为上下文——那会把整个 monoreponode_modules / .git / dist动辄数 GB发给 Docker daemon。它构造的上下文只有 5 个条目、约 2 MB几乎全是 lockfile# 等价逻辑脚本内部实现 mkdir -p tmp/review-sandbox-ctx cp mise.toml package.json pnpm-lock.yaml pnpm-workspace.yaml tmp/review-sandbox-ctx/ cp -r patches tmp/review-sandbox-ctx/ docker build -t nx-review-sandbox:latest -f tools/review-sandbox/Dockerfile tmp/review-sandbox-ctx这 5 个条目每一个都是承重的缺一不可。缺失的后果在 Dockerfile 中逐条注释条目缺了会怎样package.jsoncorepack 靠packageManager字段激活锁定的 pnpm缺失时 corepack 会静默激活最新版 pnpmpnpm-lock.yamlpnpm fetch无从解析pnpm-workspace.yaml声明了patchedDependencies及 catalog缺失则补丁机制失效patches/直接报错中止ERR_PNPM_PATCH_FILE_PATH_MISSINGmise.toml工具链版本无从锁定另外脚本每次重建上下文目录避免陈旧的 lockfile 副本残留误导构建。5.4 工具链的单一事实来源mise.toml镜像内的全部工具链由仓库根目录的 mise.toml 驱动——它同时是仓库开发环境自身的工具版本声明因此镜像与仓库永远保持同步[tools] bun 1.3 java 24 node {{ env[NODE_VERSION] | default(value26.7.0) }} maven 3.9.11 rust 1.95.0 vale 3.13.1 npm:corepack latest [tools.dotnet] version 9 os [linux, macos]Dockerfile 中的对应逻辑是mise trustmise installmise reshim。两个值得注意的点java dotnet 是硬性需求因为 nx 仓库在自己的项目图里 dogfood 了nx/dotnet和nx/gradle插件缺少它们 PR 构建会直接失败dotnet 仅对 linux/macos 声明因为 Windows 上其 vfox 插件存在已知问题。基础镜像为debian:bookworm-slim并额外安装了 mise 管理的工具不提供的系统库nx 的 napi-rs Rust 原生构建需要 C/C 工具链build-essential clang libclang-dev pkg-config libssl-dev python3.NET 运行时需要libicu72 libgssapi-krb5-2 zlib1gmise 拉取工具需要curl git unzip xz-utils ca-certificates。5.5 pnpm store 预热为什么暖而只读镜像构建的最后一步执行corepack prepare --activatepnpm fetch --lockfile-dir /work从 master 的 lockfile 预取约4200 个包进 pnpm 的内容寻址 store随后删除临时node_modules。有三个关键设计点store 是缓存不是构建产物PR checkout 仍然按它自己的 lockfile执行pnpm install——用不到的条目只是闲置新增依赖照常拉取。node_modules刻意不烤进镜像它必须与 PR 的 lockfile 精确匹配master 的缓存镜像几乎每天都在变陈旧版本会在最坏方向上失败对 PR 从未指定的版本跑绿测试暖 store 是只读的它活在镜像的下层 layer里容器内首次pnpm install必须把其 lockfile 触及的部分拷贝上可写层约 2.3 GB、耗时数分钟才能硬链接。这就是为什么所有审查共享一个宿主机容器copy-up 只付一次第二个审查的安装实测降到约0.39 GB / 12 秒若每次审查都开独立容器这 2.3 GB 就得反复付构建产物体积整套工具链安装加预热 store 耗时较长、占几个 GB其中暖 store 约 2.6 GB且要求第 1、3 步先通过——构建需要可用的网络。六、第五步冒烟验证初始化完成后用一条命令确认沙箱真的隔离、且真的带上了工具# RUNTIME--runtimerunsc 在 Linux 上 # RUNTIME 在 macOS 上 docker run --rm $RUNTIME nx-review-sandbox:latest bash -c cd /work # mise 在这里根据 mise.toml 解析版本切勿用 bash -l登录 shell 会重置 PATH丢掉 mise 目录 echo kernel: $(uname -r) # LinuxgVisor: 4.19.0-gvisor ; macOS: VM 的内核 mise ls | head node --version; java --version 21 | head -1; dotnet --version 判定绿灯的标准内核不是宿主内核Linux 上你会看到4.19.0-gvisor这样的 gVisor 内核版本号macOS 上则是 VM 的内核——这是隔离生效的直接证据node/java/dotnet都能报出版本号——工具链就位。最后按步骤汇总输出简洁的 ✅/❌并明确指出用户还需要手动执行什么通常是带 sudo 的部分。七、第六步磁盘回收与共享状态管理审查本身会自行清理sandbox stop删除该次审查的/work/id子树sandbox prune清扫注册表中已无记录的孤儿子树。但共享状态即缓存本体不在它们的清理范围内需要显式处理.claude/tools/sandbox prune --store # pnpm store 清理 共享仓库 git gc .claude/tools/sandbox prune --host # 销毁共享宿主机容器下次 start 会冷重建两条命令在任何沙箱行还存活时都会拒绝执行——那等于删除正在被某次运行中的审查读取的文件。需要理解的两个细节对应 .claude/tools/sandbox 的实现镜像重建后无需手动--host共享宿主机的名字由镜像的解析后 ID而非 tag派生。build-image.sh是原地重建nx-review-sandbox:latest若按 tag 取名后来的审查就会继续使用还跑着旧工具链的宿主机按镜像 ID 派生则下次start自动拉起新宿主机被取代的旧宿主机留给prune --host回收它的几个 GB安全边界的真实形态多个审查共享同一个 pnpm store一个恶意 PR 理论上可以污染 store、影响后续审查。但这始终发生在容器内部够不到宿主它真正的危害上限是破坏后续审查的结论不是逃逸宿主。这是该设计的威胁模型决定的隔离边界是不可信 PR 代码 vs 宿主而不是PR A vs PR B。八、与整体工作流的协同技能不是一次性用品虽然技能名字带一次性one-time但它的产物被三个地方反复依赖构成了一个自我维护的闭环review-pr 技能 的 pre-flight会无条件调用build-image.sh因此在每次审查时镜像都被顺带更新到最新——靠每次审查保持镜像新鲜取代了记得手动重跑本技能reproduce-issue 技能 的 Preflight按序检查 Docker、网络A/B 两条命令、runsc、以及仅在 PR 构建模式下的镜像存在性命中第一个缺失项就停下并打印一行修复建议大多数缺失项的修复指向本技能——以 FIX 而非谜题的方式失败reproduce-verifier Agent在 Level 2 前检查docker image inspect nx-review-sandbox:latest缺了就提示运行本技能并且宁可跳过 Level 2 也绝不在宿主上构建。一句话总结这套初始化的最终形态Docker 提供容器gVisor或 macOS 的 VM提供隔离mise.toml 锁定工具链预热的 pnpm store 让每次审查的安装从下载 4200 个包变成秒级硬链接——所有审查代码的执行都被压缩进一个可随时销毁、可随时重建的边界之内宿主自始至终只负责读与编排。【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考