cloudflare-sandbox について
Cloudflare Sandboxes SDKを使い、コンテナ内でコマンド実行やファイル管理を行うWorkersの開発を解説するスキルです。セッション、ライフサイクル、永続性に加え、セットアップと安全面の注意点を扱います。
主な機能
- 01コンテナ内でのコマンド実行
- 02ファイルの読み書きと管理
- 03複数段階の作業に使うセッション
- 04サンドボックスのライフサイクルとコールドスタート対応
- 05Git、コード実行、プロセスの管理
活用シーン
- 01Workerから隔離されたコードを実行する
- 02セッションを使った複数段階のワークフローを構築する
- 03テストやビルド用のクリーンなサンドボックスを作る
- 04アイドル時のリセットを考慮してデータ保存を設計する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill cloudflare-sandboxインストール後、Claude Code で/cloudflare-sandboxを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/example-template.txtreferences/advanced.mdapi-reference.mdcommon-errors.mdexample-reference.mdnaming-strategies.mdpatterns.mdpersistence-guide.mdsession-management.mdscripts/example-script.shsetup-sandbox-binding.shtest-sandbox.tstemplates/basic-executor.tschat-agent.tsci-cd.tsworkspace.ts詳細
Cloudflare Sandboxes SDK
ステータス: 本番環境対応(オープンベータ)
最終更新日: 2025-12-10
依存関係: cloudflare-worker-base、cloudflare-durable-objects(理解を深めるため推奨)
最新バージョン: @cloudflare/[email protected]、Docker イメージ:cloudflare/sandbox:0.6.3-python
⚠️ 重大な変更(v0.6.0): Python はデフォルトイメージに含まれなくなりました。Python を使用するには、cloudflare/sandbox:<version>-python を使用してください(データサイエンス用パッケージを含めて約 1.3GB)。軽量版(約 600~800MB)には Python は含まれません。
クイックスタート(15 分)
1. SDK をインストールして Wrangler をセットアップする
bun add @cloudflare/sandbox@latest # preferred
# or: bun add @cloudflare/sandbox@latest
wrangler.jsonc:
{
"name": "my-sandbox-worker",
"main": "src/index.ts",
"compatibility_flags": ["nodejs_compat"],
"containers": [{
"class_name": "Sandbox",
"image": "cloudflare/sandbox:0.6.3-python",
"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. 最初の Sandbox Worker を作成する
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
});
}
};
重要:
- Worker から
@cloudflare/sandboxの{ Sandbox }を必ずエクスポートしてください - Sandbox ID によってルーティング先が決まります(同じ ID なら同じコンテナ)
- 最初のリクエストでコンテナが作成されます(コールドスタートに約 2~3 分)
- 2 回目以降のリクエストは高速です(1 秒未満)
3. デプロイしてテストする
npm run deploy
curl https://your-worker.workers.dev
出力例:
{
"output": "4\n",
"success": true,
"exitCode": 0
}
安全なインストール
Sandbox SDK パッケージはコンテナへのアクセス権を付与します。無許可のコード実行を防ぐため、インストール前に確認してください。サプライチェーンセキュリティのベストプラクティスに従ってください。
- インストール後のスクリプトをブロックする —
npm config set ignore-scripts true(または Bun:デフォルトで無効) - クールダウン期間を設ける — 新しいパッケージバージョンは、コミュニティによる審査が済むまで 7 日間待ちます
- インストール前に監査する —
socket package score npm <pkg>を実行するか、socket npm install <pkg>を使用してパッケージを確認します
dependency-upgrade スキルを読み込み、Socket CLI との統合、クールダウンの設定、ロックファイルの検証、CI での適用を含む、セキュリティ設定全般を確認してください。
アーキテクチャ(3 層モデルを理解する)
Sandbox の仕組み
┌─────────────────────────────────────────┐
│ 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) │
└─────────────────────────────────────────┘
重要なポイント:Worker は API ロジックを処理し(高速)、Durable Objects はリクエストをルーティングし(永続的な ID)、コンテナはコードを実行します(すべての機能を利用可能)。
コンテナのライフサイクル(最も重要なセクション!)
コンテナの状態
┌─────────┐ 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 分間):
- ✅
/workspace、/tmp、/home内のファイルは保持されます - ✅ バックグラウンドプロセスは実行を続けます
- ✅ シェルの環境変数は保持されます
- ✅ セッションの作業ディレクトリは保持されます
コンテナがアイドル状態になると(非アクティブになった後):
- ❌ すべてのファイルが削除されます(ファイルシステム全体がリセットされます)
- ❌ すべてのプロセスが終了します
- ❌ シェルの状態がすべて失われます
- ⚠️ 次のリクエストでは、新しいコンテナが一から作成されます
これは従来のサーバーとは異なります。Sandbox は設計上、一時的なものです。
データの永続化
重要なデータの場合:外部ストレージを使用します
// 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());
}
ビルド成果物の場合:一時性を許容するか、キャッシュを使用します
// 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' });
セッション管理(チャットエージェントの強力な機能)
セッションとは?
セッションは、1 つの Sandbox 内で使用するbash シェルのコンテキストです。ターミナルのタブのようなものです。
主な特性:
- 各セッションは個別の作業ディレクトリを持ちます
- セッション間で同じファイルシステムを共有します
- 同一セッション内では、コマンド間で作業ディレクトリが保持されます
- 複数ステップのワークフローに最適です
パターン:チャットベースのコーディングエージェント
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
セッションを使わない場合(よくある間違い)
// ❌ WRONG: Each command runs in separate session
await sandbox.exec('cd /workspace/project');
await sandbox.exec('ls'); // NOT in /workspace/project (different session)
パターン:並列実行
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 })
]);
Sandbox の命名戦略
ユーザーごとの Sandbox(永続的な作業環境)
const sandbox = getSandbox(env.Sandbox, `user-${userId}`);
メリット:ユーザーがアクティブに使用している間、作業内容が保持されます(アイドル時間は 10 分) デメリット:最初のリクエストによって場所が決まります 用途:インタラクティブなノートブック、IDE、永続的な作業環境
セッションごとの Sandbox(毎回新規作成)
const sandboxId = `session-${Date.now()}-${crypto.randomUUID()}`;
const sandbox = getSandbox(env.Sandbox, sandboxId);
// Always destroy after use
await sandbox.destroy();
メリット:クリーンな環境で、状態の混入がありません デメリット:リクエスト間で状態は保持されません 用途:1 回限りのコード実行、CI/CD、テスト
タスクごとのサンドボックス(冪等性と追跡可能性)
const sandbox = getSandbox(env.Sandbox, `build-${repoName}-${commitSha}`);
メリット:再現可能、デバッグ可能、キャッシュ可能 デメリット:明示的なクリーンアップ戦略が必要 ユースケース:ビルドシステム、データパイプライン、自動化されたワークフロー
コア API リファレンス
Sandbox SDK は、コマンド実行、ファイル操作、Git 操作、コードインタープリター(Jupyter のような機能)、バックグラウンドプロセス、クリーンアップのためのメソッドを提供します。
API メソッドのシグネチャ、パラメーターのオプション、実装例の詳細が必要な場合は、📖 references/api-reference.md を読み込んでください。
- オプション(cwd、タイムアウト、環境変数、セッション)を指定したコマンドの実行
- ファイル操作(read/write/mkdir/rm/readdir)
- Git 操作(gitCheckout、Git コマンド)
- コードインタープリター(createCodeContext、runCode)
- バックグラウンドプロセス(spawn、isProcessRunning、killProcess)
- サンドボックスのクリーンアップ(destroy)
重要なルール
必ず行うこと
✅ 終了コードを確認する - if (!result.success) { handle error }
✅ 複数ステップのワークフローではセッションを使用する - 作業ディレクトリを維持します
✅ コールドスタートに対処する - ファイルが存在すると決めつけず、存在するか確認します
✅ タイムアウトを設定する - 長時間の処理で停止するのを防ぎます
✅ 一時的なサンドボックスを破棄する - 一時的/セッションベースのサンドボックスをクリーンアップします
✅ 永続化には外部ストレージを使用する - 重要なデータには R2/KV/D1 を使用します
✅ ユーザー入力を検証する - コマンドインジェクションを防ぐため、exec() の前にサニタイズします
✅ Sandbox クラスをエクスポートする - export { Sandbox } from '@cloudflare/sandbox'
絶対に行わないこと
❌ アイドル状態の後もファイルが保持されると思い込む - コンテナは約 10 分後にリセットされます
❌ 終了コードを無視する - 必ず result.success または result.exitCode を確認します
❌ セッションを使わずにコマンドを連結する - cd /dir の後に ls を実行しても機能しません
❌ サニタイズされていないユーザー入力を実行する - コードインタープリターを使用するか、十分に検証します
❌ nodejs_compat フラグを忘れる - wrangler.jsonc で必須です
❌ マイグレーションを省略する - Durable Objects にはマイグレーションエントリーが必要です
❌ プレビュー URL に .workers.dev を使用する - カスタムドメインが必要です
❌ 無制限にサンドボックスを作成する - リークを防ぐため、一時的なものは破棄します
既知の問題の防止
このスキルは、文書化されている10件の問題を防ぎます。
問題 #1:nodejs_compat フラグがない
エラー:ReferenceError: fetch is not defined または Buffer is not defined
ソース:https://developers.cloudflare.com/sandbox/get-started/
発生理由:SDK が、標準の Workers では利用できない Node.js API を必要とします
防止策:wrangler.jsonc に "compatibility_flags": ["nodejs_compat"] を追加します
問題 #2:マイグレーションがない
エラー:Error: Class 'Sandbox' not found
ソース:https://developers.cloudflare.com/durable-objects/
発生理由:Durable Objects はマイグレーションを通じて登録する必要があります
防止策:wrangler.jsonc に migrations 配列を含めます
問題 #3:ファイルの永続性を前提にする
エラー:非アクティブ状態の後にファイルが消失する ソース:https://developers.cloudflare.com/sandbox/concepts/sandboxes/ 発生理由:コンテナは約 10 分後にアイドル状態になり、すべての状態がリセットされます 防止策:外部ストレージ(R2/KV)を使用するか、リクエストごとに存在を確認します
問題 #4:セッションディレクトリの混同
エラー:コマンドが誤ったディレクトリで実行される
ソース:https://developers.cloudflare.com/sandbox/concepts/sessions/
発生理由:明示的に指定しない限り、各 exec() は新しいセッションを使用します
防止策:createSession() でセッションを作成し、関連するすべてのコマンドに渡します
問題 #5:終了コードを無視する
エラー:失敗したコマンドを成功したと思い込む
ソース:シェルのベストプラクティス
発生理由:result.success または result.exitCode を確認していません
防止策:必ず確認します:if (!result.success) throw new Error(result.stderr)
問題 #6:コールドスタートに対処しない
エラー:依存関係がインストールされていないため、コマンドが失敗する ソース:https://developers.cloudflare.com/sandbox/concepts/sandboxes/ 発生理由:アイドル期間の後にコンテナがリセットされます 防止策:コマンドを実行する前にセットアップが必要か確認します
Issue #7:Docker が実行されていない(ローカル開発)
エラー:ローカル開発中に Failed to build container
参照元:https://developers.cloudflare.com/sandbox/get-started/
原因:ローカル開発には Docker デーモンが必要です
予防策:npm run dev の実行前に Docker Desktop が起動していることを確認してください
Issue #8:バージョンの不一致(パッケージと Docker イメージ)
エラー:API メソッドが利用できない、または予期しない動作をする
参照元:GitHub の issue
原因:npm パッケージのバージョンと Docker イメージのバージョンが一致していません
予防策:@cloudflare/sandbox パッケージと cloudflare/sandbox イメージのバージョンを一致させてください
Issue #9:一時的なサンドボックスをクリーンアップしていない
エラー:リソースの枯渇、予期しないコスト
参照元:リソース管理のベストプラクティス
原因:破棄せずにサンドボックスを作成しています
予防策:一時的なサンドボックスでは、finally ブロック内で await sandbox.destroy() を実行してください
Issue #10:コマンドインジェクションの脆弱性
エラー:サニタイズされていないユーザー入力によるセキュリティ侵害
参照元:セキュリティのベストプラクティス
原因:ユーザー入力を直接 exec() に渡しています
予防策:コードインタープリター API を使用するか、入力を十分に検証・サニタイズしてください
wrangler.jsonc の例
{
"name": "my-sandbox-app",
"main": "src/index.ts",
"compatibility_date": "2025-10-29",
"compatibility_flags": ["nodejs_compat"], // ← REQUIRED
"containers": [{
"class_name": "Sandbox",
"image": "cloudflare/sandbox:0.6.3-python", // ← Use -python for Python support
"instance_type": "lite"
}],
"durable_objects": {
"bindings": [{"class_name": "Sandbox", "name": "Sandbox"}]
},
"migrations": [{
"tag": "v1",
"new_sqlite_classes": ["Sandbox"]
}]
}
よくあるパターン
Cloudflare Sandboxes を使って構築する、本番環境に対応した 4 つのパターンです。一度限りのコード実行、永続的なユーザーワークスペース、CI/CD パイプライン、AI エージェントとの統合を紹介します。
📖 完全な実装例が必要な場合は、references/patterns.md を読み込んでください。
- 一度限りのコード実行 - API エンドポイント、コードプレイグラウンド、学習プラットフォーム
- 永続的なユーザーワークスペース - インタラクティブな環境、ノートブック、IDE
- CI/CD ビルドパイプライン - ビルドシステム、テストパイプライン、デプロイの自動化
- Claude Code を使った AI エージェント - リファクタリングの自動化、コード生成、AI 開発
同梱リソースの使用
スクリプト(scripts/)
setup-sandbox-binding.sh- 対話形式での wrangler.jsonc の設定test-sandbox.ts- サンドボックスのセットアップをテストする検証スクリプト
使用例:
# Setup wrangler config
./scripts/setup-sandbox-binding.sh
# Test sandbox
bunx tsx scripts/test-sandbox.ts
参考資料(references/)
references/persistence-guide.md- コンテナのライフサイクルと永続性の詳細な解説references/session-management.md- 高度なセッションパターンとベストプラクティスreferences/common-errors.md- エラーと解決策の完全な一覧references/naming-strategies.md- ユースケースに応じたサンドボックス ID の選び方
Claude がこれらを読み込むべき場合:
- 状態の問題やコールドスタートのデバッグ時には、
persistence-guide.mdを読み込みます - 複数ステップのワークフローやチャットエージェントの構築時には、
session-management.mdを読み込みます - 特定のエラーに遭遇した場合は、
common-errors.mdを読み込みます - サンドボックスのアーキテクチャを設計する際は、
naming-strategies.mdを読み込みます
高度なトピック
本番環境向けのパターンについては、📖 references/advanced.md を読み込んでください。
- グローバルアプリ向けの地理的分散戦略
- エラーハンドリング用のラッパー関数
- セキュリティ強化と入力検証
公式リソース
パッケージ:@cloudflare/[email protected] | Docker:cloudflare/sandbox:0.6.3-python
ドキュメント:Cloudflare Sandboxes | API リファレンス | GitHub SDK