mcpField
C
cloudflare-sandbox

cloudflare-sandbox

github.com/secondskyクラウド・DevOps240222 回インストール5 週間前に更新
リポジトリ

cloudflare-sandbox について

Cloudflare Sandboxes SDKを使い、コンテナ内でコマンド実行やファイル管理を行うWorkersの開発を解説するスキルです。セッション、ライフサイクル、永続性に加え、セットアップと安全面の注意点を扱います。

主な機能

  1. 01コンテナ内でのコマンド実行
  2. 02ファイルの読み書きと管理
  3. 03複数段階の作業に使うセッション
  4. 04サンドボックスのライフサイクルとコールドスタート対応
  5. 05Git、コード実行、プロセスの管理

活用シーン

  1. 01Workerから隔離されたコードを実行する
  2. 02セッションを使った複数段階のワークフローを構築する
  3. 03テストやビルド用のクリーンなサンドボックスを作る
  4. 04アイドル時のリセットを考慮してデータ保存を設計する

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/secondsky/claude-skills --skill cloudflare-sandbox

インストール後、Claude Code で/cloudflare-sandboxを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
example-template.txt
references/
advanced.md
api-reference.md
common-errors.md
example-reference.md
naming-strategies.md
patterns.md
persistence-guide.md
session-management.md
scripts/
example-script.sh
setup-sandbox-binding.sh
test-sandbox.ts
templates/
basic-executor.ts
chat-agent.ts
ci-cd.ts
workspace.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 を読み込んでください。

  1. 一度限りのコード実行 - API エンドポイント、コードプレイグラウンド、学習プラットフォーム
  2. 永続的なユーザーワークスペース - インタラクティブな環境、ノートブック、IDE
  3. CI/CD ビルドパイプライン - ビルドシステム、テストパイプライン、デプロイの自動化
  4. 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

コメント