Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/withastro/flue/llms.txt

Use this file to discover all available pages before exploring further.

Cloudflare has native container support via @cloudflare/sandbox. When you deploy Flue to Cloudflare Workers, each agent session can get its own isolated Linux container with a persistent filesystem, full shell access, and tools like git, Node.js, and curl pre-installed.
@cloudflare/sandbox only works inside a Cloudflare Worker — it cannot be invoked from a Node.js process. Using this connector means your Flue project deploys to --target cloudflare. If you’re on --target node and want a remote sandbox, see Daytona or E2B instead.

How it differs from other connectors

Most Flue connectors install a .flue/connectors/<name>.ts adapter file. The Cloudflare connector is different: Flue’s runtime already includes the wiring for @cloudflare/sandbox on the Cloudflare target. There’s no factory file to install. You declare the sandbox in wrangler.jsonc, add a Dockerfile, and call getSandbox() directly in your agent.

Setup

1

Install @cloudflare/sandbox

npm install @cloudflare/sandbox
2

Add bindings to wrangler.jsonc

Declare the Durable Object binding, migration, and container image at your project root (alongside package.json):
{
  "$schema": "https://workers.cloudflare.com/schema/wrangler.json",
  "name": "my-agent",
  "compatibility_date": "2026-04-01",
  "compatibility_flags": ["nodejs_compat"],
  "durable_objects": {
    "bindings": [{ "class_name": "Sandbox", "name": "Sandbox" }]
  },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["Sandbox"] }],
  "containers": [{ "class_name": "Sandbox", "image": "./Dockerfile" }]
}
Any DO binding whose class_name ends with Sandbox is automatically wired by Flue. You can name it anything — Sandbox, PyBoxSandbox, SupportSandbox — as long as the name ends in Sandbox.
3

Add a Dockerfile

At the project root (the path your containers[].image points to):
FROM docker.io/cloudflare/sandbox:0.9.2
Pin the tag to match the @cloudflare/sandbox version in your package.json — they’re versioned together. Add your own RUN steps to install extra tools:
FROM docker.io/cloudflare/sandbox:0.9.2
RUN apt-get update && apt-get install -y python3 python3-pip
4

Use it in an agent

Call getSandbox(env.Sandbox, id) and pass the result directly to init(). No factory wrapper needed.
import type { FlueContext } from '@flue/runtime';
import { getSandbox } from '@cloudflare/sandbox';

export const triggers = { webhook: true };

export default async function ({ init, id, env, payload }: FlueContext) {
  // The binding name from wrangler.jsonc is the key on env.
  const sandbox = getSandbox(env.Sandbox, id);
  const harness = await init({ sandbox, model: 'anthropic/claude-opus-4-7' });
  const session = await harness.session();

  return await session.prompt(payload.message);
}

Multiple sandbox images

Different agents can use different container images. Declare a separate binding for each — every class_name must end in Sandbox:
{
  "durable_objects": {
    "bindings": [
      { "class_name": "PyBoxSandbox", "name": "PyBox" },
      { "class_name": "NodeSandbox", "name": "NodeBox" }
    ]
  },
  "migrations": [
    { "tag": "v1", "new_sqlite_classes": ["PyBoxSandbox", "NodeSandbox"] }
  ],
  "containers": [
    { "class_name": "PyBoxSandbox", "image": "./docker/python.Dockerfile" },
    { "class_name": "NodeSandbox", "image": "./docker/node.Dockerfile" }
  ]
}
Each agent grabs the sandbox it needs:
const sandbox = getSandbox(env.PyBox, id);   // Python image
const sandbox = getSandbox(env.NodeBox, id); // Node.js image

Secure egress with outbound Workers

When an agent runs inside a container, it may need to call external APIs — GitHub, npm, internal services. Instead of injecting secrets as container environment variables (where the LLM could see them), use Cloudflare’s outbound Workers to intercept outgoing requests and inject secrets at the proxy layer:
class MySandbox extends Sandbox {
  static outboundByHost = {
    'api.github.com': (request, env, ctx) => {
      const headers = new Headers(request.headers);
      headers.set('Authorization', `Bearer ${env.GITHUB_TOKEN}`);
      return fetch(request, { headers });
    },
  };
}
The container never sees the token. The proxy runs on the same machine, so latency is negligible. See the outbound Workers documentation for full details.

R2-backed virtual sandbox

If your agent only needs a searchable file store rather than a full Linux container, you can use getVirtualSandbox from @flue/runtime/cloudflare to mount an R2 bucket as the agent’s filesystem. No container, no Dockerfile — just fast, cheap, persistent storage:
import { getVirtualSandbox } from '@flue/runtime/cloudflare';
import type { FlueContext } from '@flue/runtime';

export const triggers = { webhook: true };

export default async function ({ init, payload, env }: FlueContext) {
  const sandbox = await getVirtualSandbox(env.KNOWLEDGE_BASE);
  const harness = await init({ sandbox, model: 'openrouter/moonshotai/kimi-k2.6' });
  const session = await harness.session();

  return await session.prompt(
    `Search the knowledge base and answer: ${payload.message}`,
  );
}
Add the R2 binding to wrangler.jsonc:
{
  "r2_buckets": [
    {
      "binding": "KNOWLEDGE_BASE",
      "bucket_name": "my-knowledge-base"
    }
  ]
}
The virtual sandbox is ideal for support agents, knowledge-base search, and any use case where the agent needs to grep, glob, and read files without needing a real shell environment.

Build and deploy

# Local dev (with container support)
npx flue dev --target cloudflare --env .env

# Build and deploy
npx flue build --target cloudflare
npx wrangler deploy --secrets-file .env

When to use the Cloudflare container sandbox

The Cloudflare container sandbox is the right choice when:
  • Your agents already deploy to Cloudflare Workers
  • You need a full Linux environment close to your Workers edge logic
  • You want session-persistent containers tied to a Durable Object ID
  • You want zero-trust secret injection with outbound Workers
If you’re on --target node or need a provider-managed sandbox that works across targets, see Daytona or E2B.

Resources

Build docs developers (and LLMs) love