cloudflare-sandbox

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Cloudflare Sandboxes SDK

Cloudflare Sandboxes SDK

Status: Production Ready (Open Beta) Last Updated: 2025-10-29 Dependencies:
cloudflare-worker-base
,
cloudflare-durable-objects
(recommended for understanding) Latest Versions:
@cloudflare/sandbox@0.4.12
, Docker image:
cloudflare/sandbox:0.4.12

状态:生产就绪(公开测试版) 最后更新:2025-10-29 依赖项
cloudflare-worker-base
cloudflare-durable-objects
(建议了解) 最新版本
@cloudflare/sandbox@0.4.12
,Docker镜像:
cloudflare/sandbox:0.4.12

Quick Start (15 Minutes)

快速开始(15分钟)

1. Install SDK and Setup Wrangler

1. 安装SDK并配置Wrangler

bash
npm install @cloudflare/sandbox@latest
wrangler.jsonc:
jsonc
{
  "name": "my-sandbox-worker",
  "main": "src/index.ts",
  "compatibility_flags": ["nodejs_compat"],
  "containers": [{
    "class_name": "Sandbox",
    "image": "cloudflare/sandbox:0.4.12",
    "instance_type": "lite"
  }],
  "durable_objects": {
    "bindings": [{
      "class_name": "Sandbox",
      "name": "Sandbox"
    }]
  },
  "migrations": [{
    "tag": "v1",
    "new_sqlite_classes": ["Sandbox"]
  }]
}
Why this matters:
  • nodejs_compat
    enables Node.js APIs required by SDK
  • containers
    defines the Ubuntu container image
  • durable_objects
    binding enables persistent routing
  • migrations
    registers the Sandbox class
bash
npm install @cloudflare/sandbox@latest
wrangler.jsonc:
jsonc
{
  "name": "my-sandbox-worker",
  "main": "src/index.ts",
  "compatibility_flags": ["nodejs_compat"],
  "containers": [{
    "class_name": "Sandbox",
    "image": "cloudflare/sandbox:0.4.12",
    "instance_type": "lite"
  }],
  "durable_objects": {
    "bindings": [{
      "class_name": "Sandbox",
      "name": "Sandbox"
    }]
  },
  "migrations": [{
    "tag": "v1",
    "new_sqlite_classes": ["Sandbox"]
  }]
}
配置说明:
  • nodejs_compat
    启用SDK所需的Node.js API
  • containers
    定义Ubuntu容器镜像
  • durable_objects
    绑定实现持久化路由
  • migrations
    注册Sandbox类

2. Create Your First Sandbox Worker

2. 创建第一个Sandbox Worker

typescript
import { getSandbox, type Sandbox } from '@cloudflare/sandbox';
export { Sandbox } from '@cloudflare/sandbox';

type Env = {
  Sandbox: DurableObjectNamespace<Sandbox>;
};

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // Get sandbox instance (creates if doesn't exist)
    const sandbox = getSandbox(env.Sandbox, 'my-first-sandbox');

    // Execute Python code
    const result = await sandbox.exec('python3 -c "print(2 + 2)"');

    return Response.json({
      output: result.stdout,
      success: result.success,
      exitCode: result.exitCode
    });
  }
};
CRITICAL:
  • MUST export
    { Sandbox }
    from
    @cloudflare/sandbox
    in your Worker
  • Sandbox ID determines routing (same ID = same container)
  • First request creates container (~2-3 min cold start)
  • Subsequent requests are fast (<1s)
typescript
import { getSandbox, type Sandbox } from '@cloudflare/sandbox';
export { Sandbox } from '@cloudflare/sandbox';

type Env = {
  Sandbox: DurableObjectNamespace<Sandbox>;
};

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // 获取沙箱实例(不存在则创建)
    const sandbox = getSandbox(env.Sandbox, 'my-first-sandbox');

    // 执行Python代码
    const result = await sandbox.exec('python3 -c "print(2 + 2)"');

    return Response.json({
      output: result.stdout,
      success: result.success,
      exitCode: result.exitCode
    });
  }
};
关键注意事项:
  • 必须在Worker中导出
    { Sandbox }
    来自
    @cloudflare/sandbox
  • Sandbox ID决定路由(同一ID对应同一容器)
  • 首次请求会创建容器(冷启动约2-3分钟)
  • 后续请求响应快速(<1秒)

3. Deploy and Test

3. 部署并测试

bash
npm run deploy
curl https://your-worker.workers.dev
Expected output:
json
{
  "output": "4\n",
  "success": true,
  "exitCode": 0
}

bash
npm run deploy
curl https://your-worker.workers.dev
预期输出:
json
{
  "output": "4\n",
  "success": true,
  "exitCode": 0
}

Architecture (Understanding the 3-Layer Model)

架构(理解三层模型)

How Sandboxes Work

Sandboxes工作原理

┌─────────────────────────────────────────┐
│  Your Worker (Layer 1)                  │
│  - Handles HTTP requests                │
│  - Calls getSandbox()                   │
│  - Uses sandbox.exec(), writeFile(), etc│
└──────────────┬──────────────────────────┘
               │ RPC via Durable Object
┌──────────────▼──────────────────────────┐
│  Durable Object (Layer 2)               │
│  - Routes by sandbox ID                 │
│  - Maintains persistent identity        │
│  - Geographic stickiness                │
└──────────────┬──────────────────────────┘
               │ Container API
┌──────────────▼──────────────────────────┐
│  Ubuntu Container (Layer 3)             │
│  - Full Linux environment               │
│  - Python 3.11, Node 20, Git, etc.      │
│  - Filesystem: /workspace, /tmp, /home  │
│  - Process isolation (VM-based)         │
└─────────────────────────────────────────┘
Key Insight: Workers handle API logic (fast), Durable Objects route requests (persistent identity), Containers execute code (full capabilities).

┌─────────────────────────────────────────┐
│  你的Worker(第一层)                   │
│  - 处理HTTP请求                        │
│  - 调用getSandbox()                   │
│  - 使用sandbox.exec()、writeFile()等方法│
└──────────────┬──────────────────────────┘
               │ 通过Durable Object进行RPC调用
┌──────────────▼──────────────────────────┐
│  Durable Object(第二层)               │
│  - 按sandbox ID路由请求                │
│  - 维护持久化标识                      │
│  - 地域粘性                            │
└──────────────┬──────────────────────────┘
               │ 容器API
┌──────────────▼──────────────────────────┐
│  Ubuntu容器(第三层)                   │
│  - 完整Linux环境                       │
│  - 预装Python 3.11、Node 20、Git等工具  │
│  - 文件系统:/workspace、/tmp、/home    │
│  - 基于VM的进程隔离                    │
└─────────────────────────────────────────┘
核心要点:Worker处理API逻辑(快速),Durable Object负责请求路由(持久化标识),容器执行代码(完整能力)。

Critical Container Lifecycle (Most Important Section!)

关键容器生命周期(最重要的章节!)

Container States

容器状态

┌─────────┐  First request  ┌────────┐  ~10 min idle  ┌──────┐
│ Not     │ ───────────────>│ Active │ ─────────────> │ Idle │
│ Created │                 │        │                │      │
└─────────┘                 └───┬────┘                └──┬───┘
                                │ ^                      │
                                │ │ New request          │
                                │ └──────────────────────┘
                                │                         │
                                ▼                         ▼
                            Files persist          ALL FILES DELETED
                            Processes run          ALL PROCESSES KILLED
                            State maintained       ALL STATE RESET
┌─────────┐  首次请求  ┌────────┐  闲置约10分钟  ┌──────┐
│  未创建  │ ────────────>│ 活跃中 │ ───────────> │ 闲置 │
│         │              │        │                │      │
└─────────┘              └───┬────┘                └──┬───┘
                                │ ^                      │
                                │ │ 新请求               │
                                │ └──────────────────────┘
                                │                         │
                                ▼                         ▼
                            文件保持存在          所有文件被删除
                            进程持续运行          所有进程被终止
                            状态被维护            所有状态重置

The #1 Gotcha: Ephemeral by Default

头号陷阱:默认临时特性

While Container is Active (~10 min after last request):
  • ✅ Files in
    /workspace
    ,
    /tmp
    ,
    /home
    persist
  • ✅ Background processes keep running
  • ✅ Shell environment variables remain
  • ✅ Session working directories preserved
When Container Goes Idle (after inactivity):
  • ALL files deleted (entire filesystem reset)
  • ALL processes terminated
  • ALL shell state lost
  • ⚠️ Next request creates fresh container from scratch
This is NOT like a traditional server. Sandboxes are ephemeral by design.
容器活跃时(最后一次请求后约10分钟内):
  • /workspace
    /tmp
    /home
    中的文件会保留
  • ✅ 后台进程持续运行
  • ✅ Shell环境变量保持不变
  • ✅ 会话工作目录被保留
容器闲置后(无活动后):
  • 所有文件被删除(整个文件系统重置)
  • 所有进程被终止
  • 所有Shell状态丢失
  • ⚠️ 下一次请求会从头创建全新容器
这和传统服务器不同。Sandboxes设计为临时特性。

Handling Persistence

处理持久化

For Important Data: Use external storage
typescript
// Save to R2 before container goes idle
await sandbox.writeFile('/workspace/data.txt', content);
const fileData = await sandbox.readFile('/workspace/data.txt');
await env.R2.put('backup/data.txt', fileData);

// Restore on next request
const restored = await env.R2.get('backup/data.txt');
if (restored) {
  await sandbox.writeFile('/workspace/data.txt', await restored.text());
}
For Build Artifacts: Accept ephemerality or use caching
typescript
// Check if setup needed (handles cold starts)
const exists = await sandbox.readdir('/workspace/project').catch(() => null);
if (!exists) {
  await sandbox.gitCheckout(repoUrl, '/workspace/project');
  await sandbox.exec('npm install', { cwd: '/workspace/project' });
}
// Now safe to run build
await sandbox.exec('npm run build', { cwd: '/workspace/project' });

重要数据:使用外部存储
typescript
// 在容器闲置前保存到R2
await sandbox.writeFile('/workspace/data.txt', content);
const fileData = await sandbox.readFile('/workspace/data.txt');
await env.R2.put('backup/data.txt', fileData);

// 下次请求时恢复
const restored = await env.R2.get('backup/data.txt');
if (restored) {
  await sandbox.writeFile('/workspace/data.txt', await restored.text());
}
构建产物:接受临时特性或使用缓存
typescript
// 检查是否需要初始化(处理冷启动)
const exists = await sandbox.readdir('/workspace/project').catch(() => null);
if (!exists) {
  await sandbox.gitCheckout(repoUrl, '/workspace/project');
  await sandbox.exec('npm install', { cwd: '/workspace/project' });
}
// 现在可以安全执行构建
await sandbox.exec('npm run build', { cwd: '/workspace/project' });

Session Management (Game-Changer for Chat Agents)

会话管理(对话式Agent的关键特性)

What Are Sessions?

什么是会话?

Sessions are bash shell contexts within one sandbox. Think terminal tabs.
Key Properties:
  • Each session has separate working directory
  • Sessions share same filesystem
  • Working directory persists across commands in same session
  • Perfect for multi-step workflows
会话是单个沙箱内的bash Shell上下文,可以理解为终端标签页。
核心特性
  • 每个会话有独立的工作目录
  • 会话共享同一文件系统
  • 同一会话内的命令会保留工作目录
  • 完美适配多步骤工作流

Pattern: Chat-Based Coding Agent

模式:基于对话的编码Agent

typescript
type ConversationState = {
  sandboxId: string;
  sessionId: string;
};

// First message: Create sandbox and session
const sandboxId = `user-${userId}`;
const sandbox = getSandbox(env.Sandbox, sandboxId);
const sessionId = await sandbox.createSession();

// Store in conversation state (database, KV, etc.)
await env.KV.put(`conversation:${conversationId}`, JSON.stringify({
  sandboxId,
  sessionId
}));

// Later messages: Reuse same session
const state = await env.KV.get(`conversation:${conversationId}`);
const { sandboxId, sessionId } = JSON.parse(state);
const sandbox = getSandbox(env.Sandbox, sandboxId);

// Commands run in same context
await sandbox.exec('cd /workspace/project', { session: sessionId });
await sandbox.exec('ls -la', { session: sessionId }); // Still in /workspace/project
await sandbox.exec('git status', { session: sessionId }); // Still in /workspace/project
typescript
type ConversationState = {
  sandboxId: string;
  sessionId: string;
};

// 第一条消息:创建沙箱和会话
const sandboxId = `user-${userId}`;
const sandbox = getSandbox(env.Sandbox, sandboxId);
const sessionId = await sandbox.createSession();

// 存储对话状态(数据库、KV等)
await env.KV.put(`conversation:${conversationId}`, JSON.stringify({
  sandboxId,
  sessionId
}));

// 后续消息:复用同一会话
const state = await env.KV.get(`conversation:${conversationId}`);
const { sandboxId, sessionId } = JSON.parse(state);
const sandbox = getSandbox(env.Sandbox, sandboxId);

// 命令在同一上下文中执行
await sandbox.exec('cd /workspace/project', { session: sessionId });
await sandbox.exec('ls -la', { session: sessionId }); // 仍处于/workspace/project目录
await sandbox.exec('git status', { session: sessionId }); // 仍处于/workspace/project目录

Without Sessions (Common Mistake)

错误用法(常见误区)

typescript
// ❌ WRONG: Each command runs in separate session
await sandbox.exec('cd /workspace/project');
await sandbox.exec('ls'); // NOT in /workspace/project (different session)
typescript
// ❌ 错误:每个命令在独立会话中运行
await sandbox.exec('cd /workspace/project');
await sandbox.exec('ls'); // 不在/workspace/project目录(不同会话)

Pattern: Parallel Execution

模式:并行执行

typescript
const session1 = await sandbox.createSession();
const session2 = await sandbox.createSession();

// Run different tasks simultaneously
await Promise.all([
  sandbox.exec('python train_model.py', { session: session1 }),
  sandbox.exec('node generate_reports.js', { session: session2 })
]);

typescript
const session1 = await sandbox.createSession();
const session2 = await sandbox.createSession();

// 同时运行不同任务
await Promise.all([
  sandbox.exec('python train_model.py', { session: session1 }),
  sandbox.exec('node generate_reports.js', { session: session2 })
]);

Sandbox Naming Strategies

Sandbox命名策略

Per-User Sandboxes (Persistent Workspace)

按用户划分(持久化工作区)

typescript
const sandbox = getSandbox(env.Sandbox, `user-${userId}`);
Pros: User's work persists while actively using (10 min idle time) Cons: Geographic lock-in (first request determines location) Use Cases: Interactive notebooks, IDEs, persistent workspaces
typescript
const sandbox = getSandbox(env.Sandbox, `user-${userId}`);
优点:用户工作内容在活跃期间保留(闲置10分钟内) 缺点:地域锁定(首次请求决定位置) 适用场景:交互式笔记本、IDE、持久化工作区

Per-Session Sandboxes (Fresh Each Time)

按会话划分(每次全新环境)

typescript
const sandboxId = `session-${Date.now()}-${crypto.randomUUID()}`;
const sandbox = getSandbox(env.Sandbox, sandboxId);
// Always destroy after use
await sandbox.destroy();
Pros: Clean environment, no state pollution Cons: No persistence between requests Use Cases: One-shot code execution, CI/CD, testing
typescript
const sandboxId = `session-${Date.now()}-${crypto.randomUUID()}`;
const sandbox = getSandbox(env.Sandbox, sandboxId);
// 使用后务必销毁
await sandbox.destroy();
优点:环境干净,无状态污染 缺点:请求间无持久化 适用场景:一次性代码执行、CI/CD、测试

Per-Task Sandboxes (Idempotent & Traceable)

按任务划分(幂等且可追溯)

typescript
const sandbox = getSandbox(env.Sandbox, `build-${repoName}-${commitSha}`);
Pros: Reproducible, debuggable, cacheable Cons: Need explicit cleanup strategy Use Cases: Build systems, data pipelines, automated workflows

typescript
const sandbox = getSandbox(env.Sandbox, `build-${repoName}-${commitSha}`);
优点:可重现、可调试、可缓存 缺点:需要显式清理策略 适用场景:构建系统、数据管道、自动化工作流

Core API Reference

核心API参考

Getting a Sandbox

获取沙箱

typescript
import { getSandbox } from '@cloudflare/sandbox';

const sandbox = getSandbox(env.Sandbox, 'unique-sandbox-id');
// Creates new sandbox if doesn't exist, or gets existing one
typescript
import { getSandbox } from '@cloudflare/sandbox';

const sandbox = getSandbox(env.Sandbox, 'unique-sandbox-id');
// 不存在则创建新沙箱,否则获取已有沙箱

Executing Commands

执行命令

typescript
// Basic execution
const result = await sandbox.exec('python3 script.py');
console.log(result.stdout);   // Standard output
console.log(result.stderr);   // Standard error
console.log(result.exitCode); // Exit code (0 = success)
console.log(result.success);  // Boolean (exitCode === 0)

// With options
const result = await sandbox.exec('npm install', {
  cwd: '/workspace/project',        // Working directory
  timeout: 120000,                   // Timeout in ms (default: 30s)
  session: sessionId,                // Session ID
  env: { NODE_ENV: 'production' }   // Environment variables
});

// Always check exit codes!
if (!result.success) {
  throw new Error(`Command failed: ${result.stderr}`);
}
typescript
// 基础执行
const result = await sandbox.exec('python3 script.py');
console.log(result.stdout);   // 标准输出
console.log(result.stderr);   // 标准错误
console.log(result.exitCode); // 退出码(0=成功)
console.log(result.success);  // 布尔值(exitCode === 0)

// 带选项的执行
const result = await sandbox.exec('npm install', {
  cwd: '/workspace/project',        // 工作目录
  timeout: 120000,                   // 超时时间(毫秒,默认30秒)
  session: sessionId,                // 会话ID
  env: { NODE_ENV: 'production' }   // 环境变量
});

// 务必检查退出码!
if (!result.success) {
  throw new Error(`命令执行失败: ${result.stderr}`);
}

File Operations

文件操作

typescript
// Write file
await sandbox.writeFile('/workspace/data.txt', 'content');

// Read file
const content = await sandbox.readFile('/workspace/data.txt');

// Create directory
await sandbox.mkdir('/workspace/project', { recursive: true });

// List directory
const files = await sandbox.readdir('/workspace');
console.log(files); // ['data.txt', 'project']

// Delete file/directory
await sandbox.rm('/workspace/data.txt');
await sandbox.rm('/workspace/project', { recursive: true });
typescript
// 写入文件
await sandbox.writeFile('/workspace/data.txt', 'content');

// 读取文件
const content = await sandbox.readFile('/workspace/data.txt');

// 创建目录
await sandbox.mkdir('/workspace/project', { recursive: true });

// 列出目录内容
const files = await sandbox.readdir('/workspace');
console.log(files); // ['data.txt', 'project']

// 删除文件/目录
await sandbox.rm('/workspace/data.txt');
await sandbox.rm('/workspace/project', { recursive: true });

Git Operations

Git操作

typescript
// Clone repository (optimized, faster than exec('git clone'))
await sandbox.gitCheckout(
  'https://github.com/user/repo',
  '/workspace/repo'
);

// Now use standard git commands
await sandbox.exec('git status', { cwd: '/workspace/repo' });
await sandbox.exec('git diff', { cwd: '/workspace/repo' });
typescript
// 克隆仓库(优化过,比exec('git clone')更快)
await sandbox.gitCheckout(
  'https://github.com/user/repo',
  '/workspace/repo'
);

// 之后使用标准Git命令
await sandbox.exec('git status', { cwd: '/workspace/repo' });
await sandbox.exec('git diff', { cwd: '/workspace/repo' });

Code Interpreter (Jupyter-like)

代码解释器(类Jupyter)

typescript
// Create Python context
const ctx = await sandbox.createCodeContext({ language: 'python' });

// Execute code - last expression auto-returned
const result = await sandbox.runCode(`
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
df['a'].sum()  # This value is automatically returned
`, { context: ctx });

console.log(result.results[0].text); // "6"
console.log(result.logs); // Output from print() statements
console.log(result.error); // Any errors
typescript
// 创建Python上下文
const ctx = await sandbox.createCodeContext({ language: 'python' });

// 执行代码 - 最后一个表达式自动返回
const result = await sandbox.runCode(`
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
df['a'].sum()  // 该值会自动返回
`, { context: ctx });

console.log(result.results[0].text); // "6"
console.log(result.logs); // print()语句的输出
console.log(result.error); // 任何错误信息

Background Processes

后台进程

typescript
// Start long-running process
const proc = await sandbox.spawn('python server.py');
console.log(proc.pid);

// Check if still running
const running = await sandbox.isProcessRunning(proc.pid);

// Kill process
await sandbox.killProcess(proc.pid);
typescript
// 启动长期运行的进程
const proc = await sandbox.spawn('python server.py');
console.log(proc.pid);

// 检查进程是否仍在运行
const running = await sandbox.isProcessRunning(proc.pid);

// 终止进程
await sandbox.killProcess(proc.pid);

Cleanup

清理

typescript
// Destroy sandbox permanently
await sandbox.destroy();
// All files deleted, container removed, cannot be recovered

typescript
// 永久销毁沙箱
await sandbox.destroy();
// 所有文件被删除,容器被移除,无法恢复

Critical Rules

关键规则

Always Do

务必遵守

Check exit codes -
if (!result.success) { handle error }
Use sessions for multi-step workflows - Preserve working directory ✅ Handle cold starts - Check if files exist before assuming they're there ✅ Set timeouts - Prevent hanging on long operations ✅ Destroy ephemeral sandboxes - Cleanup temp/session-based sandboxes ✅ Use external storage for persistence - R2/KV/D1 for important data ✅ Validate user input - Sanitize before exec() to prevent command injection ✅ Export Sandbox class -
export { Sandbox } from '@cloudflare/sandbox'
检查退出码 -
if (!result.success) { 处理错误 }
多步骤工作流使用会话 - 保留工作目录 ✅ 处理冷启动 - 执行命令前检查文件是否存在 ✅ 设置超时 - 防止长时间操作挂起 ✅ 销毁临时沙箱 - 清理临时/会话型沙箱 ✅ 重要数据使用外部存储 - R2/KV/D1存储重要数据 ✅ 验证用户输入 - 执行exec()前进行 sanitize 防止命令注入 ✅ 导出Sandbox类 -
export { Sandbox } from '@cloudflare/sandbox'

Never Do

严禁操作

Assume files persist after idle - Container resets after ~10 min ❌ Ignore exit codes - Always check
result.success
or
result.exitCode
Chain commands without sessions -
cd /dir
then
ls
won't work ❌ Execute unsanitized user input - Use code interpreter or validate thoroughly ❌ Forget nodejs_compat flag - Required in wrangler.jsonc ❌ Skip migrations - Durable Objects need migration entries ❌ Use .workers.dev for preview URLs - Need custom domain ❌ Create unlimited sandboxes - Destroy ephemeral ones to avoid leaks

假设文件在闲置后仍保留 - 容器约10分钟后重置 ❌ 忽略退出码 - 务必检查
result.success
result.exitCode
无会话时链式执行命令 -
cd /dir
后执行
ls
不会生效 ❌ 执行未 sanitize 的用户输入 - 使用代码解释器或彻底验证 ❌ 忘记nodejs_compat标志 - wrangler.jsonc中必须添加 ❌ 跳过迁移配置 - Durable Objects需要迁移条目 ❌ 使用.workers.dev作为预览URL - 需要自定义域名 ❌ 创建无限沙箱 - 销毁临时沙箱避免资源泄漏

Known Issues Prevention

已知问题预防

This skill prevents 10 documented issues:
本技能可预防10个已记录的问题:

Issue #1: Missing nodejs_compat Flag

问题1:缺少nodejs_compat标志

Error:
ReferenceError: fetch is not defined
or
Buffer is not defined
Source: https://developers.cloudflare.com/sandbox/get-started/ Why It Happens: SDK requires Node.js APIs not available in standard Workers Prevention: Add
"compatibility_flags": ["nodejs_compat"]
to wrangler.jsonc
错误
ReferenceError: fetch is not defined
Buffer is not defined
来源https://developers.cloudflare.com/sandbox/get-started/ 原因:SDK需要标准Worker中未提供的Node.js API 解决:在wrangler.jsonc中添加
"compatibility_flags": ["nodejs_compat"]

Issue #2: Missing Migrations

问题2:缺少迁移配置

Error:
Error: Class 'Sandbox' not found
Source: https://developers.cloudflare.com/durable-objects/ Why It Happens: Durable Objects must be registered via migrations Prevention: Include migrations array in wrangler.jsonc
错误
Error: Class 'Sandbox' not found
来源https://developers.cloudflare.com/durable-objects/ 原因:Durable Objects必须通过迁移注册 解决:在wrangler.jsonc中包含migrations数组

Issue #3: Assuming File Persistence

问题3:假设文件永久保留

Error: Files disappear after inactivity Source: https://developers.cloudflare.com/sandbox/concepts/sandboxes/ Why It Happens: Containers go idle after ~10 min, all state reset Prevention: Use external storage (R2/KV) or check existence on each request
错误:闲置后文件消失 来源https://developers.cloudflare.com/sandbox/concepts/sandboxes/ 原因:容器闲置约10分钟后会重置所有状态 解决:使用R2/KV进行持久化,或每次请求前检查并重建环境

Issue #4: Session Directory Confusion

问题4:会话目录混乱

Error: Commands execute in wrong directory Source: https://developers.cloudflare.com/sandbox/concepts/sessions/ Why It Happens: Each exec() uses new session unless explicitly specified Prevention: Create session with
createSession()
, pass to all related commands
错误:命令在错误目录执行 来源https://developers.cloudflare.com/sandbox/concepts/sessions/ 原因:除非显式指定,否则每个exec()使用新会话 解决:使用
createSession()
创建会话,所有相关命令传入该会话ID

Issue #5: Ignoring Exit Codes

问题5:忽略退出码

Error: Assuming command succeeded when it failed Source: Shell best practices Why It Happens: Not checking
result.success
or
result.exitCode
Prevention: Always check:
if (!result.success) throw new Error(result.stderr)
错误:假设命令执行成功但实际失败 来源:Shell最佳实践 原因:未检查
result.success
result.exitCode
解决:务必检查:
if (!result.success) throw new Error(result.stderr)

Issue #6: Not Handling Cold Starts

问题6:未处理冷启动

Error: Commands fail because dependencies aren't installed Source: https://developers.cloudflare.com/sandbox/concepts/sandboxes/ Why It Happens: Container resets after idle period Prevention: Check if setup needed before running commands
错误:因依赖未安装导致命令执行失败 来源https://developers.cloudflare.com/sandbox/concepts/sandboxes/ 原因:容器闲置后会重置 解决:执行命令前检查是否需要初始化

Issue #7: Docker Not Running (Local Dev)

问题7:本地开发时Docker未运行

Error:
Failed to build container
during local development Source: https://developers.cloudflare.com/sandbox/get-started/ Why It Happens: Local dev requires Docker daemon Prevention: Ensure Docker Desktop is running before
npm run dev
错误:本地开发时
Failed to build container
来源https://developers.cloudflare.com/sandbox/get-started/ 原因:本地开发需要Docker守护进程 解决
npm run dev
前确保Docker Desktop已运行

Issue #8: Version Mismatch (Package vs Docker Image)

问题8:版本不匹配(包与Docker镜像)

Error: API methods not available or behaving unexpectedly Source: GitHub issues Why It Happens: npm package version doesn't match Docker image version Prevention: Keep
@cloudflare/sandbox
package and
cloudflare/sandbox
image in sync
错误:API方法不可用或行为异常 来源:GitHub issues 原因:npm包版本与Docker镜像版本不一致 解决:保持
@cloudflare/sandbox
包和
cloudflare/sandbox
镜像版本同步

Issue #9: Not Cleaning Up Ephemeral Sandboxes

问题9:未清理临时沙箱

Error: Resource exhaustion, unexpected costs Source: Resource management best practices Why It Happens: Creating sandboxes without destroying them Prevention:
await sandbox.destroy()
in finally block for temp sandboxes
错误:资源耗尽、意外成本 来源:资源管理最佳实践 原因:创建沙箱后未销毁 解决:临时沙箱在finally块中执行
await sandbox.destroy()

Issue #10: Command Injection Vulnerability

问题10:命令注入漏洞

Error: Security breach from unsanitized user input Source: Security best practices Why It Happens: Passing user input directly to
exec()
Prevention: Use code interpreter API or validate/sanitize input thoroughly

错误:未 sanitize 的用户输入导致安全漏洞 来源:安全最佳实践 原因:直接将用户输入传入
exec()
解决:使用代码解释器API或彻底验证/ sanitize 输入

Configuration Files Reference

配置文件参考

wrangler.jsonc (Full Example)

wrangler.jsonc(完整示例)

jsonc
{
  "name": "my-sandbox-app",
  "main": "src/index.ts",
  "compatibility_date": "2025-10-29",
  "compatibility_flags": ["nodejs_compat"],

  "containers": [{
    "class_name": "Sandbox",
    "image": "cloudflare/sandbox:0.4.12",
    "instance_type": "lite"
  }],

  "durable_objects": {
    "bindings": [{
      "class_name": "Sandbox",
      "name": "Sandbox"
    }]
  },

  "migrations": [{
    "tag": "v1",
    "new_sqlite_classes": ["Sandbox"]
  }],

  "env": {
    "ANTHROPIC_API_KEY": {
      "description": "Optional: For AI features"
    }
  },

  "observability": {
    "enabled": true
  }
}
Why these settings:
  • nodejs_compat
    : Required for SDK to work
  • containers.image
    : Specific version ensures consistency
  • instance_type: "lite"
    : Smallest instance, upgrade to "large" for more resources
  • migrations
    : Registers Sandbox Durable Object class
  • observability
    : Enable logging for debugging
jsonc
{
  "name": "my-sandbox-app",
  "main": "src/index.ts",
  "compatibility_date": "2025-10-29",
  "compatibility_flags": ["nodejs_compat"],

  "containers": [{
    "class_name": "Sandbox",
    "image": "cloudflare/sandbox:0.4.12",
    "instance_type": "lite"
  }],

  "durable_objects": {
    "bindings": [{
      "class_name": "Sandbox",
      "name": "Sandbox"
    }]
  },

  "migrations": [{
    "tag": "v1",
    "new_sqlite_classes": ["Sandbox"]
  }],

  "env": {
    "ANTHROPIC_API_KEY": {
      "description": "可选:用于AI功能"
    }
  },

  "observability": {
    "enabled": true
  }
}
配置说明:
  • nodejs_compat
    :SDK运行必需
  • containers.image
    :指定版本确保一致性
  • instance_type: "lite"
    :最小实例规格,资源需求高时升级为"large"
  • migrations
    :注册Sandbox Durable Object类
  • observability
    :启用日志用于调试

Dockerfile (Optional - For Local Dev)

Dockerfile(可选 - 本地开发)

Only needed if extending base image:
dockerfile
FROM cloudflare/sandbox:0.4.12
仅在扩展基础镜像时需要:
dockerfile
FROM cloudflare/sandbox:0.4.12

Install additional tools

安装额外工具

RUN apt-get update && apt-get install -y
ffmpeg
imagemagick
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y
ffmpeg
imagemagick
&& rm -rf /var/lib/apt/lists/*

Expose port for preview URLs (local dev only)

暴露端口用于预览URL(仅本地开发)

EXPOSE 8080

---
EXPOSE 8080

---

Common Patterns

常见模式

Pattern 1: One-Shot Code Execution

模式1:一次性代码执行

typescript
export default {
  async fetch(request: Request, env: Env) {
    const { code, language } = await request.json();

    // Create ephemeral sandbox
    const sandboxId = `exec-${Date.now()}-${crypto.randomUUID()}`;
    const sandbox = getSandbox(env.Sandbox, sandboxId);

    try {
      // Create code context
      const ctx = await sandbox.createCodeContext({ language });

      // Execute code safely
      const result = await sandbox.runCode(code, {
        context: ctx,
        timeout: 10000
      });

      return Response.json({
        result: result.results?.[0]?.text,
        logs: result.logs,
        error: result.error
      });
    } finally {
      // Always cleanup
      await sandbox.destroy();
    }
  }
};
When to use: API endpoints for code execution, code playgrounds, learning platforms
typescript
export default {
  async fetch(request: Request, env: Env) {
    const { code, language } = await request.json();

    // 创建临时沙箱
    const sandboxId = `exec-${Date.now()}-${crypto.randomUUID()}`;
    const sandbox = getSandbox(env.Sandbox, sandboxId);

    try {
      // 创建代码上下文
      const ctx = await sandbox.createCodeContext({ language });

      // 安全执行代码
      const result = await sandbox.runCode(code, {
        context: ctx,
        timeout: 10000
      });

      return Response.json({
        result: result.results?.[0]?.text,
        logs: result.logs,
        error: result.error
      });
    } finally {
      // 务必清理
      await sandbox.destroy();
    }
  }
};
适用场景:代码执行API端点、代码 playground、学习平台

Pattern 2: Persistent User Workspace

模式2:持久化用户工作区

typescript
export default {
  async fetch(request: Request, env: Env) {
    const userId = request.headers.get('X-User-ID');
    const { command, sessionId: existingSession } = await request.json();

    // User-specific sandbox (persists while active)
    const sandbox = getSandbox(env.Sandbox, `user-${userId}`);

    // Get or create session
    let sessionId = existingSession;
    if (!sessionId) {
      sessionId = await sandbox.createSession();
    }

    // Execute command in persistent context
    const result = await sandbox.exec(command, {
      session: sessionId,
      timeout: 30000
    });

    return Response.json({
      sessionId, // Return for next request
      output: result.stdout,
      error: result.stderr,
      success: result.success
    });
  }
};
When to use: Interactive coding environments, notebooks, IDEs, development workspaces
typescript
export default {
  async fetch(request: Request, env: Env) {
    const userId = request.headers.get('X-User-ID');
    const { command, sessionId: existingSession } = await request.json();

    // 用户专属沙箱(活跃期间持久化)
    const sandbox = getSandbox(env.Sandbox, `user-${userId}`);

    // 获取或创建会话
    let sessionId = existingSession;
    if (!sessionId) {
      sessionId = await sandbox.createSession();
    }

    // 在持久化上下文中执行命令
    const result = await sandbox.exec(command, {
      session: sessionId,
      timeout: 30000
    });

    return Response.json({
      sessionId, // 返回给下一次请求
      output: result.stdout,
      error: result.stderr,
      success: result.success
    });
  }
};
适用场景:交互式编码环境、笔记本、IDE、开发工作区

Pattern 3: CI/CD Build Pipeline

模式3:CI/CD构建流水线

typescript
async function runBuild(repoUrl: string, commit: string, env: Env) {
  const sandboxId = `build-${repoUrl.split('/').pop()}-${commit}`;
  const sandbox = getSandbox(env.Sandbox, sandboxId);

  try {
    // Clone repository
    await sandbox.gitCheckout(repoUrl, '/workspace/repo');

    // Checkout specific commit
    await sandbox.exec(`git checkout ${commit}`, {
      cwd: '/workspace/repo'
    });

    // Install dependencies
    const install = await sandbox.exec('npm install', {
      cwd: '/workspace/repo',
      timeout: 180000 // 3 minutes
    });

    if (!install.success) {
      throw new Error(`Install failed: ${install.stderr}`);
    }

    // Run build
    const build = await sandbox.exec('npm run build', {
      cwd: '/workspace/repo',
      timeout: 300000 // 5 minutes
    });

    if (!build.success) {
      throw new Error(`Build failed: ${build.stderr}`);
    }

    // Save artifacts to R2
    const dist = await sandbox.exec('tar -czf dist.tar.gz dist', {
      cwd: '/workspace/repo'
    });
    const artifact = await sandbox.readFile('/workspace/repo/dist.tar.gz');
    await env.R2.put(`builds/${commit}.tar.gz`, artifact);

    return { success: true, artifactKey: `builds/${commit}.tar.gz` };
  } finally {
    // Optional: Keep sandbox for debugging or destroy
    // await sandbox.destroy();
  }
}
When to use: Build systems, testing pipelines, deployment automation
typescript
async function runBuild(repoUrl: string, commit: string, env: Env) {
  const sandboxId = `build-${repoUrl.split('/').pop()}-${commit}`;
  const sandbox = getSandbox(env.Sandbox, sandboxId);

  try {
    // 克隆仓库
    await sandbox.gitCheckout(repoUrl, '/workspace/repo');

    // 切换到指定提交
    await sandbox.exec(`git checkout ${commit}`, {
      cwd: '/workspace/repo'
    });

    // 安装依赖
    const install = await sandbox.exec('npm install', {
      cwd: '/workspace/repo',
      timeout: 180000 // 3分钟
    });

    if (!install.success) {
      throw new Error(`安装失败: ${install.stderr}`);
    }

    // 执行构建
    const build = await sandbox.exec('npm run build', {
      cwd: '/workspace/repo',
      timeout: 300000 // 5分钟
    });

    if (!build.success) {
      throw new Error(`构建失败: ${build.stderr}`);
    }

    // 将构建产物保存到R2
    const dist = await sandbox.exec('tar -czf dist.tar.gz dist', {
      cwd: '/workspace/repo'
    });
    const artifact = await sandbox.readFile('/workspace/repo/dist.tar.gz');
    await env.R2.put(`builds/${commit}.tar.gz`, artifact);

    return { success: true, artifactKey: `builds/${commit}.tar.gz` };
  } finally {
    // 可选:保留沙箱用于调试或销毁
    // await sandbox.destroy();
  }
}
适用场景:构建系统、测试流水线、部署自动化

Pattern 4: AI Agent with Claude Code

模式4:集成Claude Code的AI Agent

typescript
async function runClaudeCodeOnRepo(
  repoUrl: string,
  task: string,
  env: Env
): Promise<{ diff: string; logs: string }> {
  const sandboxId = `claude-${Date.now()}`;
  const sandbox = getSandbox(env.Sandbox, sandboxId);

  try {
    // Clone repository
    await sandbox.gitCheckout(repoUrl, '/workspace/repo');

    // Run Claude Code CLI with secure environment injection
    // ⚠️ SECURITY: Use env option instead of shell export to prevent key exposure in logs
    const result = await sandbox.exec(
      `claude -p "${task}" --permission-mode acceptEdits`,
      {
        cwd: '/workspace/repo',
        timeout: 300000, // 5 minutes
        env: {
          ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY
        }
      }
    );

    // Get diff of changes
    const diff = await sandbox.exec('git diff', {
      cwd: '/workspace/repo'
    });

    return {
      diff: diff.stdout,
      logs: result.stdout
    };
  } finally {
    await sandbox.destroy();
  }
}
When to use: Automated code refactoring, code generation, AI-powered development

typescript
async function runClaudeCodeOnRepo(
  repoUrl: string,
  task: string,
  env: Env
): Promise<{ diff: string; logs: string }> {
  const sandboxId = `claude-${Date.now()}`;
  const sandbox = getSandbox(env.Sandbox, sandboxId);

  try {
    // 克隆仓库
    await sandbox.gitCheckout(repoUrl, '/workspace/repo');

    // 运行Claude Code CLI并安全注入环境变量
    // ⚠️ 安全提示:使用env选项而非Shell export,避免密钥在日志中暴露
    const result = await sandbox.exec(
      `claude -p "${task}" --permission-mode acceptEdits`,
      {
        cwd: '/workspace/repo',
        timeout: 300000, // 5分钟
        env: {
          ANTHROPIC_API_KEY: env.ANTHROPIC_API_KEY
        }
      }
    );

    // 获取变更差异
    const diff = await sandbox.exec('git diff', {
      cwd: '/workspace/repo'
    });

    return {
      diff: diff.stdout,
      logs: result.stdout
    };
  } finally {
    await sandbox.destroy();
  }
}
适用场景:自动化代码重构、代码生成、AI驱动开发

Using Bundled Resources

使用内置资源

Scripts (scripts/)

脚本(scripts/)

  • setup-sandbox-binding.sh
    - Interactive wrangler.jsonc configuration
  • test-sandbox.ts
    - Validation script to test sandbox setup
Example Usage:
bash
undefined
  • setup-sandbox-binding.sh
    - 交互式wrangler.jsonc配置脚本
  • test-sandbox.ts
    - 验证沙箱配置的测试脚本
使用示例:
bash
undefined

Setup wrangler config

配置wrangler

./scripts/setup-sandbox-binding.sh
./scripts/setup-sandbox-binding.sh

Test sandbox

测试沙箱

npx tsx scripts/test-sandbox.ts
undefined
npx tsx scripts/test-sandbox.ts
undefined

References (references/)

参考文档(references/)

  • references/persistence-guide.md
    - Deep dive on container lifecycle and persistence
  • references/session-management.md
    - Advanced session patterns and best practices
  • references/common-errors.md
    - Complete list of errors with solutions
  • references/naming-strategies.md
    - Choosing sandbox IDs for different use cases
When Claude should load these:
  • Load
    persistence-guide.md
    when debugging state issues or cold starts
  • Load
    session-management.md
    when building multi-step workflows or chat agents
  • Load
    common-errors.md
    when encountering specific errors
  • Load
    naming-strategies.md
    when designing sandbox architecture

  • references/persistence-guide.md
    - 容器生命周期与持久化深度指南
  • references/session-management.md
    - 高级会话模式与最佳实践
  • references/common-errors.md
    - 完整错误列表与解决方案
  • references/naming-strategies.md
    - 不同场景下的沙箱ID选择策略
Claude应加载这些文档的场景
  • 调试状态问题或冷启动时加载
    persistence-guide.md
  • 构建多步骤工作流或对话Agent时加载
    session-management.md
  • 遇到特定错误时加载
    common-errors.md
  • 设计沙箱架构时加载
    naming-strategies.md

Advanced Topics

高级主题

Geographic Distribution

地域分布

First request to a sandbox ID determines its geographic location (via Durable Objects).
For Global Apps:
typescript
// Option 1: Multiple sandboxes per user (better latency)
const region = request.cf?.colo || 'default';
const sandbox = getSandbox(env.Sandbox, `user-${userId}-${region}`);

// Option 2: Single sandbox (simpler, higher latency for distant users)
const sandbox = getSandbox(env.Sandbox, `user-${userId}`);
首次请求沙箱ID时会确定其地理位置(通过Durable Objects)。
全球应用方案
typescript
// 方案1:每个用户多个沙箱(更低延迟)
const region = request.cf?.colo || 'default';
const sandbox = getSandbox(env.Sandbox, `user-${userId}-${region}`);

// 方案2:单个沙箱(更简单,远程用户延迟更高)
const sandbox = getSandbox(env.Sandbox, `user-${userId}`);

Error Handling Strategy

错误处理策略

typescript
async function safeSandboxExec(
  sandbox: Sandbox,
  cmd: string,
  options?: any
) {
  try {
    const result = await sandbox.exec(cmd, {
      ...options,
      timeout: options?.timeout || 30000
    });

    if (!result.success) {
      console.error(`Command failed: ${cmd}`, {
        exitCode: result.exitCode,
        stderr: result.stderr
      });

      return {
        success: false,
        error: result.stderr,
        exitCode: result.exitCode
      };
    }

    return {
      success: true,
      output: result.stdout,
      exitCode: 0
    };
  } catch (error) {
    console.error(`Sandbox error:`, error);
    return {
      success: false,
      error: error.message,
      exitCode: -1
    };
  }
}
typescript
async function safeSandboxExec(
  sandbox: Sandbox,
  cmd: string,
  options?: any
) {
  try {
    const result = await sandbox.exec(cmd, {
      ...options,
      timeout: options?.timeout || 30000
    });

    if (!result.success) {
      console.error(`命令执行失败: ${cmd}`, {
        exitCode: result.exitCode,
        stderr: result.stderr
      });

      return {
        success: false,
        error: result.stderr,
        exitCode: result.exitCode
      };
    }

    return {
      success: true,
      output: result.stdout,
      exitCode: 0
    };
  } catch (error) {
    console.error(`沙箱错误:`, error);
    return {
      success: false,
      error: error.message,
      exitCode: -1
    };
  }
}

Security Hardening

安全加固

typescript
// Input validation
function sanitizeCommand(input: string): string {
  const dangerous = ['rm -rf', '$(', '`', '&&', '||', ';', '|'];
  for (const pattern of dangerous) {
    if (input.includes(pattern)) {
      throw new Error(`Dangerous pattern detected: ${pattern}`);
    }
  }
  return input;
}

// Use code interpreter instead of direct exec for untrusted code
async function executeUntrustedCode(code: string, sandbox: Sandbox) {
  const ctx = await sandbox.createCodeContext({ language: 'python' });
  return await sandbox.runCode(code, { context: ctx, timeout: 10000 });
}

typescript
// 输入验证
function sanitizeCommand(input: string): string {
  const dangerous = ['rm -rf', '$(', '`', '&&', '||', ';', '|'];
  for (const pattern of dangerous) {
    if (input.includes(pattern)) {
      throw new Error(`检测到危险模式: ${pattern}`);
    }
  }
  return input;
}

// 不可信代码使用代码解释器而非直接exec
async function executeUntrustedCode(code: string, sandbox: Sandbox) {
  const ctx = await sandbox.createCodeContext({ language: 'python' });
  return await sandbox.runCode(code, { context: ctx, timeout: 10000 });
}

Dependencies

依赖项

Required:
  • @cloudflare/sandbox@0.4.12
    - Sandbox SDK
  • wrangler@latest
    - Deployment CLI
  • Docker Desktop - Local development only
Optional:
  • @anthropic-ai/sdk
    - For AI features
  • @cloudflare/workers-types
    - TypeScript types

必需:
  • @cloudflare/sandbox@0.4.12
    - Sandbox SDK
  • wrangler@latest
    - 部署CLI
  • Docker Desktop - 仅本地开发需要
可选:
  • @anthropic-ai/sdk
    - 用于AI功能
  • @cloudflare/workers-types
    - TypeScript类型定义

Official Documentation

官方文档

Package Versions (Verified 2025-10-29)

包版本(2025-10-29验证)

json
{
  "dependencies": {
    "@cloudflare/sandbox": "^0.4.12"
  },
  "devDependencies": {
    "wrangler": "^3.80.0",
    "@cloudflare/workers-types": "^4.20241106.0"
  }
}
Docker Image:
cloudflare/sandbox:0.4.12

json
{
  "dependencies": {
    "@cloudflare/sandbox": "^0.4.12"
  },
  "devDependencies": {
    "wrangler": "^3.80.0",
    "@cloudflare/workers-types": "^4.20241106.0"
  }
}
Docker镜像:
cloudflare/sandbox:0.4.12

Production Example

生产示例

This skill is based on official Cloudflare tutorials:

本技能基于官方Cloudflare教程:

Troubleshooting

故障排除

Problem: "Class 'Sandbox' not found"

问题:"Class 'Sandbox' not found"

Solution: Add migrations to wrangler.jsonc and ensure
export { Sandbox }
in Worker
解决: 在wrangler.jsonc中添加迁移配置,并确保Worker中
export { Sandbox }

Problem: Files disappear after some time

问题:文件一段时间后消失

Solution: Container goes idle after ~10 min. Use R2/KV for persistence or rebuild environment
解决: 容器闲置约10分钟后会重置。使用R2/KV进行持久化,或重建环境

Problem: Commands execute in wrong directory

问题:命令在错误目录执行

Solution: Create session with
createSession()
, pass sessionId to all related commands
解决: 使用
createSession()
创建会话,所有相关命令传入sessionId

Problem: Docker error during local dev

问题:本地开发时Docker错误

Solution: Ensure Docker Desktop is running before
npm run dev
解决:
npm run dev
前确保Docker Desktop已运行

Problem: "fetch is not defined"

问题:"fetch is not defined"

Solution: Add
"compatibility_flags": ["nodejs_compat"]
to wrangler.jsonc

解决: 在wrangler.jsonc中添加
"compatibility_flags": ["nodejs_compat"]

Complete Setup Checklist

完整配置检查清单

  • npm install @cloudflare/sandbox@latest
  • Add
    nodejs_compat
    to compatibility_flags
  • Add containers configuration with correct image version
  • Add Durable Objects binding
  • Add migrations for Sandbox class
  • Export Sandbox class in Worker:
    export { Sandbox } from '@cloudflare/sandbox'
  • Docker Desktop running (local dev only)
  • Test with simple exec command
  • Verify exit codes are being checked
  • Implement cleanup for ephemeral sandboxes
  • Test cold start behavior

Questions? Issues?
  1. Check
    references/common-errors.md
    for specific error solutions
  2. Verify all steps in wrangler.jsonc configuration
  3. Check official docs: https://developers.cloudflare.com/sandbox/
  4. Ensure Docker is running for local development
  5. Confirm package version matches Docker image version
  • npm install @cloudflare/sandbox@latest
  • 在compatibility_flags中添加
    nodejs_compat
  • 添加容器配置并指定正确镜像版本
  • 添加Durable Objects绑定
  • 为Sandbox类添加迁移配置
  • 在Worker中导出Sandbox类:
    export { Sandbox } from '@cloudflare/sandbox'
  • Docker Desktop已运行(仅本地开发)
  • 使用简单exec命令测试
  • 验证退出码检查逻辑
  • 实现临时沙箱的清理逻辑
  • 测试冷启动行为

有疑问?遇到问题?
  1. 查看
    references/common-errors.md
    获取特定错误解决方案
  2. 验证wrangler.jsonc中的所有配置步骤
  3. 查看官方文档: https://developers.cloudflare.com/sandbox/
  4. 本地开发确保Docker已运行
  5. 确认包版本与Docker镜像版本一致