sandbox-migrate-to-next
用途
该技能用于把已有的 Cloudflare Sandbox 应用从稳定版 @cloudflare/sandbox 迁移到 @cloudflare/sandbox@next(Sandbox SDK 1.0 预览版)。按资料说明,已有应用应当尽早迁移,以便在 1.0 成为稳定版时做好准备;但不得在用户未同意的情况下强制切换生产环境。新项目应直接使用 @next(sandbox-next),不应使用本技能;日常稳定版工作应使用 sandbox-stable。若只需清理已弃用 API 而不迁移到 @next,应先参考 2026 弃用指南。
主要能力(替换映射)
资料给出稳定版与 @next 的替换关系:
SANDBOX_TRANSPORT/transport/setTransport:移除,仅保留 RPC。await sandbox.exec("cmd")(返回缓冲结果)→await sandbox.exec(argv)(返回进程句柄),再通过 output / waits 获取结果。execStream/startProcess:改为同一句柄,提供 logs、waitFor*、kill。- 默认 / 命名会话:移除,改为每次启动时指定 cwd/env,或使用一个 shell 脚本。
sandbox.terminal(request)/ 会话终端 →createTerminal+terminal.connect(request)。- xterm 的
sessionId→terminalId。 - Sandbox 上的解释器方法 →
withInterpreter→sandbox.interpreter.*。 gitCheckout→ 通过 exec 调用 argv 形式的 git。- 字符串形式的 kill 信号 → 仅支持数字。
- Files、mounts、backups、ports、tunnels、proxyToSandbox 基本不变(忽略稳定版页面中的 session/transport 部分)。
工作流
- 审阅硬性规则与替换映射。
- 审计代码库,列出命中项与目标形态。
- 与用户确认(是否切换、桥接、Python 镜像、未覆盖的调用点)。
- 升级包、镜像与代码。
- 验证。
任何需要用户决策的步骤之后必须停下。审计可用如下正则:
rg 'SANDBOX_TRANSPORT|transport:|setTransport|enableDefaultSession|createSession|getSession|deleteSession|execStream\(|startProcess\(|killProcess\(|sandbox\.terminal\(|sessionId|gitCheckout\(|SandboxTransport|ExecutionSession'
同时留意字符串形式的 exec(、先 cd 再后续 exec、以及在 Sandbox 上直接 createCodeContext / runCode。
硬性规则
- Worker 包与容器镜像必须是同一条
@next版本线。 - 生产切换使用立即容器滚动:
npx wrangler deploy --containers-rollout=immediate。稳定版与@next控制协议双向不兼容;渐进式滚动会留下混合状态的故障窗口。进行中的容器工作可能被中断。 - 切换后
await sandbox.exec(...)表示进程已启动,而非命令已完成。 - argv 按原样传入(无隐式 shell),shell 语法需显式指定 shell 二进制。
- 进程句柄没有 stdin,交互式输入使用终端。
- 观察超时 / AbortSignal 只取消等待,不取消进程。
- 不存在适用于所有错误的单一重试循环。
- 不得臆造 API(如 core 上的 gitCheckout、进程 stdin、字符串 exec 完成辅助函数)。
- 自部署桥接保持稳定版(尚不属于预览线)。
升级与代码调整
安装:
npm install @cloudflare/sandbox@next
Dockerfile:
FROM cloudflare/sandbox:next
# Python: cloudflare/sandbox:next-python
不在浮动 next 上时,Worker 与镜像使用相同的预发布标签。
命令形态示例(保留原样):
// Before (stable)
const result = await sandbox.exec("npm test");
// After (@next)
const process = await sandbox.exec(["/bin/bash", "-lc", "npm test"]);
const result = await process.output({ encoding: "utf8" });
const server = await sandbox.exec(["/bin/bash", "-lc", "npm run dev"], {
cwd: "/workspace/app",
});
await server.waitForPort(3000, { timeout: 60_000 });
await server.kill(); // numeric; default 15
终端形态:
const terminal = await sandbox.createTerminal({ command: ["bash"], cwd: "/workspace" });
const t = await sandbox.getTerminal(terminal.id);
if (!t) return new Response("terminal gone", { status: 410 });
return t.connect(request, { cursor, cols, rows });
解释器形态:
import { Sandbox as BaseSandbox } from "@cloudflare/sandbox";
import { withInterpreter } from "@cloudflare/sandbox/interpreter";
export class Sandbox extends BaseSandbox<Env> {
interpreter = withInterpreter(this);
}
Git 形态:
const clone = await sandbox.exec(
["git", "clone", "--depth", "1", "--", repoUrl, "/workspace/repo"],
{ cwd: "/workspace" },
);
const result = await clone.output({ encoding: "utf8" });
删除传输设置,移除会话 API;使用不同的 sandbox ID 隔离用户。
部署:先在预发/分支验证,生产是一次部署匹配的 Worker 与镜像:
npx wrangler deploy --containers-rollout=immediate
保持 rollout_active_grace_period 为默认值 0(若被调高则设为 0)。切换后,部署前的进程/终端 ID 失效。
验证清单
- Lockfile 与 Dockerfile 位于同一
@next版本线。 - 针对
@next进行类型检查。 - 冒烟测试 argv exec 与
output({ encoding: "utf8" })。 - 如使用长进程 / 终端 / 解释器,进行相应冒烟测试。
- 区分错误类型:unavailable / interrupted-RPC / stale / local wait。
- 沙箱环境变量中不含实际密钥。
- 再次 grep 已移除的 API。
- 生产使用
--containers-rollout=immediate。
适用场景与限制
适用于仍在稳定版 @cloudflare/sandbox 上、需要提前适配 1.0 预览版的应用。限制包括:必须经用户同意才能切换生产;自部署桥接保持稳定版;不得混用 @next Worker 与稳定版镜像(反之亦然);不得使用渐进式容器滚动;不得把 await exec 当作命令完成;不得假设 cd 或导出变量跨 exec 持久化;不得为所有错误套用单一重试;不得臆造 gitCheckout、进程 stdin 或未文档化 API;切换后不得沿用旧进程/终端 ID;不得把实际密钥放入 setEnvVars / 启动环境。关于具体用量、价格或平台支持等其余信息,资料未提供。