问题:你有一个正常运行的 Cloudflare Sandbox 应用,但底层正在发生变化
你在 Cloudflare 的 Sandbox 平台上构建了一个应用。它运行正常,团队每天都在使用。然后你听说稳定的 @cloudflare/sandbox SDK 即将迎来重大版本变更——Sandbox SDK 1.0——而预览版已经以 @cloudflare/sandbox@next 的形式发布。
你的第一反应可能是等到它变成稳定版再说。但这里有个问题:这次迁移不是简单的版本升级。新 SDK 改变了核心 API,移除了会话和传输层等概念,并且改变了进程执行和观察的方式。如果你等到最后一刻,就只能在压力下匆忙迁移。
真正的痛点不是迁移本身——而是不确定性。到底什么变了?你现有的哪些模式会中断?如何在切换过程中避免生产事故?如何在不花几周时间阅读文档的情况下验证一切是否正常工作?
这就是拥有一个结构化、有针对性的迁移工作流的价值所在。不是通用指南,而是一个了解具体替换模式、不可违反的硬性规则以及精确步骤顺序的技能。
为什么这次迁移不仅仅是版本升级
Cloudflare Sandbox SDK 1.0 预览版(@next)不向后兼容。这是一次重新设计。实际影响如下:
- 会话被移除。 稳定版 SDK 使用会话来管理状态、环境和终端。
@nextSDK 完全移除了会话,改为在每次进程启动时配置cwd和env。 - 传输层被移除。 稳定版 SDK 有
SANDBOX_TRANSPORT、setTransport及相关配置。@nextSDK 仅使用 RPC——没有传输抽象层。 - 进程执行形式改变。 稳定版中
await sandbox.exec("npm test")返回缓冲结果。在@next中,它返回一个进程句柄,你必须显式调用.output()来获取结果。 - 终端工作方式不同。 稳定版的
sandbox.terminal(request)模式被createTerminal+terminal.connect(request)替代。 - Git 操作需要手动处理。 稳定版 SDK 有
gitCheckout辅助方法。@nextSDK 期望你通过exec使用 argv 调用git。 - 终止信号仅支持数字。 不再支持字符串形式的信号名称。
这些不是边缘情况——它们是影响几乎所有 Sandbox 应用的核心 API 变更。如果你的代码库使用了这些模式中的任何一种,简单的 npm install @cloudflare/sandbox@next 会立即导致应用中断。
一个好的迁移方案应该做什么
一个有用的迁移工具或技能应该:
- 审计你的代码库,找出所有需要变更的模式,而不仅仅是显而易见的那些。
- 提供清晰的替换映射,让你确切知道每个稳定版 API 在
@next中变成什么。 - 强制执行硬性规则,违反这些规则会导致生产故障(比如混用
@nextWorker 和稳定版容器镜像)。 - 引导切换顺序,避免意外部署不兼容的 Worker 和镜像组合。
- 包含验证步骤,在确认迁移完成之前验证其是否成功。
- 知道何时停下来请求人工输入——特别是在生产切换时间和自部署桥接方面。
介绍 sandbox-migrate-to-next 技能
sandbox-migrate-to-next 技能是一个专门为这次迁移设计的结构化工作流。它不是通用的 Cloudflare 工具——它专注于一个任务:将现有应用从稳定版 @cloudflare/sandbox 移植到 @cloudflare/sandbox@next。
以下是它能做和不能做的事情:
适用于:
- 目前使用稳定版 SDK 的现有 Cloudflare Sandbox 应用
- 为即将到来的 1.0 稳定版做准备的团队
- 需要保留现有功能的迁移
不适用于:
- 新项目(应使用
sandbox-next技能) - 在稳定版 SDK 上的日常开发(应使用
sandbox-stable技能) - 不迁移到
@next的情况下清理已弃用 API(应使用 2026 弃用指南)
迁移工作流如何运作
该技能遵循五步流程,并在需要时设置检查点停下来请求你的输入。
第一步:审查硬性规则和替换映射
在修改任何代码之前,技能会确立不可协商的规则:
- Worker 包和容器镜像必须在同一个
@next版本线上。混用版本会导致应用中断。 - 生产切换需要使用
--containers-rollout=immediate。渐进式部署会创建不兼容的混合窗口,稳定版和@next的控制协议会冲突。 - 切换后,
await sandbox.exec(...)表示进程已启动,而不是已完成。这是一个根本性的行为变化。 - 进程句柄没有 stdin。你不能向运行中的进程管道传输交互式输入。
- 没有通用的错误重试循环。不同的错误(不可用、中断的 RPC、过期句柄、本地等待超时)需要不同的处理方式。
技能还提供完整的替换映射:
| 稳定版模式 | @next 等价物 |
|---|---|
SANDBOX_TRANSPORT / transport / setTransport |
完全移除——仅 RPC |
await sandbox.exec("cmd") → 缓冲结果 |
await sandbox.exec(argv) → 句柄,然后 .output() |
execStream / startProcess |
同一句柄:.logs、.waitFor*、.kill |
| 默认/命名会话 | 移除——每次启动使用 cwd/env |
sandbox.terminal(request) |
createTerminal + terminal.connect(request) |
gitCheckout |
通过 exec 使用 argv 调用 git |
| 字符串终止信号 | 仅支持数字 |
第二步:审计代码库
技能运行针对性搜索,找出每个需要变更的模式:
rg 'SANDBOX_TRANSPORT|transport:|setTransport|enableDefaultSession|createSession|getSession|deleteSession|execStream\(|startProcess\(|killProcess\(|sandbox\.terminal\(|sessionId|gitCheckout\(|SandboxTransport|ExecutionSession'
它还会查找更隐蔽的模式:字符串形式的 exec( 调用、cd 后跟后续 exec 调用(状态不会持久化),以及 Sandbox 上的裸 createCodeContext / runCode 使用。
第三步:与用户确认
这是技能停下来提问的地方。它需要你的输入:
- 生产切换时间。 你是否接受使用
--containers-rollout=immediate?部署过程中活跃的进程、终端和流会停止。 - 自部署桥接。 如果你有自部署桥接,它保持在稳定版上。桥接目前还不是预览版的一部分。
- Python 解释器。 如果你的应用使用 Python,你需要
-python镜像变体(cloudflare/sandbox:next-python)。 - 不明确的调用点。 任何无法清晰映射到替换表的代码都需要人工判断。
第四步:升级包、镜像和代码
技能按顺序应用变更:
包和镜像:
npm install @cloudflare/sandbox@next
FROM cloudflare/sandbox:next
按区域的代码变更:
对于命令,形式从单个字符串变为 argv 数组:
// 之前(稳定版)
const result = await sandbox.exec("npm test");
// 之后(@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(); // 数字;默认 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 隔离用户。
第五步:验证
技能运行验证清单:
- Lockfile 和 Dockerfile 在同一个
@next版本线上 - 针对
@next类型的类型检查通过 - 冒烟测试:argv
exec+output({ encoding: "utf8" })正常工作 - 冒烟测试:长时间运行的进程、终端和解释器(如果使用)
- 错误处理区分不可用、中断的 RPC、过期和本地等待错误
- sandbox 环境中没有活跃的密钥
- Grep 确认所有已移除的 API 已被清除
- 生产部署使用了
--containers-rollout=immediate
何时使用此技能(何时不使用)
在以下情况使用:
- 你有一个使用稳定版 SDK 的现有 Cloudflare Sandbox 应用
- 你想为 1.0 稳定版做准备
- 你需要一个带安全检查的结构化迁移路径
在以下情况不要使用:
- 你正在开始一个新项目(应使用
sandbox-next) - 你在稳定版 SDK 上进行日常开发(应使用
sandbox-stable) - 你想在不迁移到
@next的情况下清理已弃用的 API
使用此技能前需要检查什么
在运行此迁移之前,请检查:
- 仓库信号。 该技能来自 Cloudflare 官方的 skills 仓库(2600+ 星,Apache-2.0 许可证)。由平台团队维护。
- 安全级别。 评级为中等。迁移涉及包更改、Dockerfile 修改和生产部署命令。在应用之前审查变更。
- 文档深度。 技能为每个区域引用特定的 Cloudflare 文档页面(进程、终端、解释器、错误、生命周期)。它在步骤需要详细信息时获取这些文档,而不是依赖记忆。
- 你的代码库复杂性。 如果你有自部署桥接、自定义传输配置或大量会话使用,预计在澄清步骤中会有更多手动决策。
- 生产影响。 切换是即时的,会中断进行中的工作。请计划一个维护窗口。
需要注意的危险信号
技能明确指出会导致问题的模式:
- 混用
@nextWorker 和稳定版镜像(或反之) - 对此次切换使用渐进式容器部署
- 将
await exec视为命令完成(它只是进程启动) - 假设
cd或环境变量导出在exec调用之间持久化 - 对每种错误类型使用同一个重试包装器
- 发明 API,如核心上的
gitCheckout、进程 stdin 或未记录的辅助方法 - 部署后保留切换前的进程或终端 ID
- 未经用户同意强制进行生产切换
总结
从 Cloudflare Sandbox 稳定版迁移到 @next 是一项重要但可管理的任务。sandbox-migrate-to-next 技能为你提供了一个结构化的工作流,涵盖审计、代码变更、切换和验证。它知道何时停下来请求你的输入,并强制执行防止生产故障的硬性规则。
目标不是让迁移变得不可见——而是让它变得可预测。你会确切知道什么变了、为什么变了,以及如何验证它是否正常工作。