Sandbox Bridge 是一个参考实现的 Cloudflare Worker,它将 Sandbox SDK 作为 HTTP API 公开。任何 HTTP 客户端 — Python 脚本、Node.js 服务、CI 流水线 — 都可以创建并控制 sandbox,而无需编写 Worker。
Sandbox SDK 专为在 Cloudflare Workers 内部使用而设计。如果你的应用程序运行在 Workers 生态系统之外,它将无法直接与 sandbox 进行交互。
Bridge 将 Sandbox SDK 作为标准的 HTTP API 公开,因此你可以从任何语言或平台创建和控制 sandbox。
主要 Sandbox SDK 方法 映射到单独的 HTTP 端点。Bridge 添加了身份验证、输入验证、工作区路径限定,以及用于即时容器启动的可选 热池 (warm pool)。
将 Bridge Worker 部署到你的 Cloudflare 账户:
该按钮部署 Worker 并生成用于身份验证的 SANDBOX_API_KEY secret。当部署完成时,请记录你的 Worker URL 和 API 密钥 — 本页上的每个示例都使用它们。
手动部署
如果你希望一步步部署,请构建项目脚手架并手动部署。
先决条件:
- 一个启用了 Containers / Sandbox beta 的 Cloudflare 账户 ↗。
- Node.js ↗ 和 npm。
- 本地运行的 Docker ↗ —
wrangler deploy会从 Bridge 的Dockerfile构建容器镜像。
步骤:
-
构建 Bridge 项目脚手架:
npm create cloudflare -- sandbox-bridge --template=cloudflare/sandbox-sdk/bridge/worker cd sandbox-bridge -
进行 Cloudflare 身份认证:
npx wrangler login -
设置 API 密钥 secret。选择任意强 Token 值 — 客户端必须将此作为 Bearer token 发送:
openssl rand -hex 32 | tee /dev/stderr | npx wrangler secret put SANDBOX_API_KEY该密钥会打印到终端并管道传输给 Wrangler。请保存它 — 你需要它来对 API 请求进行身份验证。
-
部署 Worker:
npx wrangler deploy -
验证部署:
curl https://cloudflare-sandbox-bridge.<your-subdomain>.workers.dev/health你应该能看到
{"ok":true}。
Bridge 的 Dockerfile 扩展了 cloudflare/sandbox ↗ 基础镜像,并预安装了常用的 Agent 工具:
- 语言: Python 3.13, Node.js, Bun
- 工具: git, ripgrep, curl, wget, jq, tar, sed, gawk, procps
你可以自定义 Dockerfile 以添加你的工作负载所需的语言、系统包或工具。
所有示例均假设设置了以下环境变量:
export SANDBOX_API_URL=https://cloudflare-sandbox-bridge.<your-subdomain>.workers.dev
export SANDBOX_API_KEY=<your-token># 创建 sandbox
SANDBOX_ID=$(curl -s -X POST "$SANDBOX_API_URL/v1/sandbox" \
-H "Authorization: Bearer $SANDBOX_API_KEY" | jq -r '.id')
echo "Sandbox ID: $SANDBOX_ID"
# 运行命令
curl -s -X POST "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/exec" \
-H "Authorization: Bearer $SANDBOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"argv": ["sh", "-lc", "echo hello from the sandbox"], "timeout_ms": 10000}'
# 完成后销毁 sandbox
curl -s -X DELETE "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID" \
-H "Authorization: Bearer $SANDBOX_API_KEY"const API_URL = process.env.SANDBOX_API_URL;
const API_KEY = process.env.SANDBOX_API_KEY;
const headers = {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
};
// 创建 sandbox
const { id } = await fetch(`${API_URL}/v1/sandbox`, {
method: "POST",
headers,
}).then((r) => r.json());
console.log(`Sandbox ID: ${id}`);
// 运行命令
// 响应为带有以下 SSE 事件的 text/event-stream:
// event: stdout — data 为 Base64 编码的输出块
// event: stderr — data 为 Base64 编码的错误块
// event: exit — data 为 JSON: {"exit_code": 0}
// event: error — data 为 JSON: {"error": "...", "code": "..."}
const execRes = await fetch(`${API_URL}/v1/sandbox/${id}/exec`, {
method: "POST",
headers,
body: JSON.stringify({
argv: ["sh", "-lc", "echo hello from the sandbox"],
timeout_ms: 10000,
}),
});
console.log(await execRes.text());
// 完成后销毁 sandbox
await fetch(`${API_URL}/v1/sandbox/${id}`, {
method: "DELETE",
headers,
});# /// script
# dependencies = ["httpx"]
# ///
import os
import httpx
API_URL = os.environ["SANDBOX_API_URL"]
API_KEY = os.environ["SANDBOX_API_KEY"]
headers = {"Authorization": f"Bearer {API_KEY}"}
# 创建 sandbox
resp = httpx.post(f"{API_URL}/v1/sandbox", headers=headers)
sandbox_id = resp.json()["id"]
print(f"Sandbox ID: {sandbox_id}")
# 运行命令
# 响应为带有以下 SSE 事件的 text/event-stream:
# event: stdout — data 为 Base64 编码的输出块
# event: stderr — data 为 Base64 编码的错误块
# event: exit — data 为 JSON: {"exit_code": 0}
# event: error — data 为 JSON: {"error": "...", "code": "..."}
exec_resp = httpx.post(
f"{API_URL}/v1/sandbox/{sandbox_id}/exec",
headers=headers,
json={
"argv": ["sh", "-lc", "echo hello from the sandbox"],
"timeout_ms": 10000,
},
)
print(exec_resp.text)
# 完成后销毁 sandbox
httpx.delete(f"{API_URL}/v1/sandbox/{sandbox_id}", headers=headers)# 写入文件
curl -s -X PUT "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/file/workspace/hello.py" \
-H "Authorization: Bearer $SANDBOX_API_KEY" \
--data-binary 'print("hello world")'
# 读取文件
curl -s "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/file/workspace/hello.py" \
-H "Authorization: Bearer $SANDBOX_API_KEY"// 写入文件
await fetch(`${API_URL}/v1/sandbox/${id}/file/workspace/hello.py`, {
method: "PUT",
headers,
body: 'print("hello world")',
});
// 读取文件
const content = await fetch(
`${API_URL}/v1/sandbox/${id}/file/workspace/hello.py`,
{ headers },
).then((r) => r.text());
console.log(content);# /// script
# dependencies = ["httpx"]
# ///
import os
import httpx
API_URL = os.environ["SANDBOX_API_URL"]
API_KEY = os.environ["SANDBOX_API_KEY"]
SANDBOX_ID = os.environ["SANDBOX_ID"] # 来自 "创建 sandbox" 步骤
headers = {"Authorization": f"Bearer {API_KEY}"}
# 写入文件
httpx.put(
f"{API_URL}/v1/sandbox/{SANDBOX_ID}/file/workspace/hello.py",
headers=headers,
content=b'print("hello world")',
)
# 读取文件
content = httpx.get(
f"{API_URL}/v1/sandbox/{SANDBOX_ID}/file/workspace/hello.py",
headers=headers,
).text
print(content)Bridge 的大部分逻辑都在 @cloudflare/sandbox 包中。要引入最新的改进:
-
更新 SDK 依赖项:
npm update @cloudflare/sandbox -
重新部署:
npx wrangler deploy
查看 sandbox-sdk releases ↗ 以了解可能需要手动更新的 Dockerfile 或 Bridge 配置更改。
Bridge 的源代码和示例可以在 GitHub 上找到:
- Bridge 源代码 ↗ — Worker, Dockerfile, 部署脚本, 以及 OpenAPI schema。
- Workspace chat 示例 ↗ — 带有文件浏览器侧边栏的全栈聊天应用程序。
- 基础示例 ↗ — 使用 OpenAI Agents SDK 的单次 Python 编码 agent。
- HTTP API reference — Bridge API 的完整路由参考。
- 快速入门 — 直接在 Workers 上构建你的第一个 sandbox 应用程序。
- 架构 (Architecture) — Sandbox SDK 如何分层 Workers, Durable Objects 和 Containers。
- API 参考 — 完整的 Sandbox SDK 方法参考。
- OpenAI Agents SDK 教程 — 使用 Bridge 构建 Python 编码 agent。