Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/content/docs/sandbox/coding-agents/claude-code.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Run [Claude Code](https://code.claude.com/docs/en/overview) in a Linux sandbox t

RUN npm install --global @anthropic-ai/claude-code@2.1.308

COPY --from=docker.io/cloudflare/sandbox:1.0.1 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim
COPY --from=docker.io/cloudflare/sandbox:1.0.1 \
/usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim

WORKDIR /workspace
CMD ["sleep", "infinity"]
Expand Down
3 changes: 2 additions & 1 deletion src/content/docs/sandbox/coding-agents/codex.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Run the [Codex CLI](https://developers.openai.com/codex/cli) in a Linux sandbox

RUN npm install --global --ignore-scripts @openai/codex@0.156.1

COPY --from=docker.io/cloudflare/sandbox:1.0.1 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim
COPY --from=docker.io/cloudflare/sandbox:1.0.1 \
/usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim

WORKDIR /workspace
CMD ["sleep", "infinity"]
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/sandbox/coding-agents/cursor.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ To stream controller and container logs, run:
npx wrangler tail
```

To list container instances, find the ID of the container application, then list its instances:
To list containers, find the ID of the container application, then list its containers:

```sh
npx wrangler containers list
Expand Down
3 changes: 2 additions & 1 deletion src/content/docs/sandbox/coding-agents/opencode.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Run [OpenCode](https://opencode.ai) in a Linux sandbox to edit a GitHub reposito
RUN npm install --global --ignore-scripts opencode-linux-x64-baseline@1.19.4 \
&& ln -s /usr/local/lib/node_modules/opencode-linux-x64-baseline/bin/opencode /usr/local/bin/opencode

COPY --from=docker.io/cloudflare/sandbox:1.0.1 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim
COPY --from=docker.io/cloudflare/sandbox:1.0.1 \
/usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim

WORKDIR /workspace
CMD ["sleep", "infinity"]
Expand Down
3 changes: 2 additions & 1 deletion src/content/docs/sandbox/coding-agents/pi.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Run the [Pi](https://github.com/earendil-works/pi) coding agent in a Linux sandb

RUN npm install --global --ignore-scripts @earendil-works/pi-coding-agent@0.87.1

COPY --from=docker.io/cloudflare/sandbox:1.0.1 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim
COPY --from=docker.io/cloudflare/sandbox:1.0.1 \
/usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim

WORKDIR /workspace
CMD ["sleep", "infinity"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ A development server prints a line, such as `ready`, when it accepts requests. T
```ts
// Prints the first matching line and exits with 0. Exits with 3 when the
// process ends without printing one, 4 when there is no such process, and
// 5 when the process was lost, for example in an earlier instance.
// 5 when the process was lost, for example in an earlier container.
const WAIT = `${CURRENT}
dir=$1; pattern=$2
[ -d "$dir" ] || exit 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { PackageManagers, Steps, TypeScriptExample } from "~/components";

Start a server that runs until the container stops, such as a development server, a tunnel, or a code kernel. Unlike a job, nothing waits for the server to exit. Your Durable Object starts it on first use, waits until it answers, and starts it again in each new container.

For a process that runs until it finishes, such as a build or an agent task, refer to [Run background processes](/sandbox/commands/run-background-processes/). If the sandbox runs one server and keeps no files that you need, you can make the server the main process instead, as in [Preview a web application](/sandbox/previews/). The main process is the process that the container starts with, and the container stops when it exits. For more information, refer to [What stops an instance](/sandbox/concepts/lifetime/#what-stops-an-instance).
For a process that runs until it finishes, such as a build or an agent task, refer to [Run background processes](/sandbox/commands/run-background-processes/). If the sandbox runs one server and keeps no files that you need, you can make the server the main process instead, as in [Preview a web application](/sandbox/previews/). The main process is the process that the container starts with, and the container stops when it exits. For more information, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#what-stops-an-instance).

## Prerequisites

Expand All @@ -35,7 +35,7 @@ For a process that runs until it finishes, such as a build or an agent task, ref
const INACTIVITY_TIMEOUT_MS = 10 * 60 * 1000;

// Defines current(), which reads the process ID in a directory into $pid
// when the process started in this instance.
// when the process started in this container.
const CURRENT = `current() {
read -r pid boot 2>/dev/null <"$1/pid" &&
[ "$boot" = "$(cat /proc/sys/kernel/random/boot_id)" ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ For a process that runs until the container stops, such as a development server
echo "$?" >"$dir/exit-code.tmp" && mv "$dir/exit-code.tmp" "$dir/exit-code"`;

// Defines current(), which reads the process ID in a directory into $pid
// when the process started in this instance.
// when the process started in this container.
const CURRENT = `current() {
read -r pid boot 2>/dev/null <"$1/pid" &&
[ "$boot" = "$(cat /proc/sys/kernel/random/boot_id)" ]
Expand Down
4 changes: 2 additions & 2 deletions src/content/docs/sandbox/concepts/security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Isolation does not limit what the code does inside its own sandbox. Assume that

## Everything in one sandbox is shared

Every process in a Container runs in the same Linux environment, the [container instance](/sandbox/concepts/lifetime/). The processes can read the same files, see each other, and connect to the servers that other processes run on `localhost`. Code loaded into one Dynamic Worker shares its memory in the same way.
Every process in a [Container](/sandbox/concepts/lifetime/) runs in the same Linux environment. The processes can read the same files, see each other, and connect to the servers that other processes run on `localhost`. Code loaded into one Dynamic Worker shares its memory in the same way.

A separate Linux user does not keep a command away from files. `root` is the privileged Linux user. In a deployed sandbox, every process has the Linux capabilities of `root`, even when it runs under another user ID, so file permissions do not restrict it, and it can switch back to `root`. For more information, refer to the [`exec()` `user` option](/containers/api/durable-object-container/#exec).

Expand Down Expand Up @@ -50,7 +50,7 @@ A Container keeps its files while it runs. A snapshot saves those files, includi

The name decides which sandbox, and which saved files, a request reaches. It does not show who sent the request. Authenticate the caller in your Worker, and derive the sandbox name from that identity. Reusing a name or a snapshot for someone else gives them the earlier user's files. The how-to guides read the name from the URL only to keep the examples short.

For more information about what a sandbox keeps between instances, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#snapshots-carry-files-to-the-next-instance).
For more information about what a sandbox keeps between containers, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#snapshots-carry-files-to-the-next-instance).

## Every opening is also a way out

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Back up a directory to R2
description: Save a directory from a Linux sandbox to your R2 bucket, and restore it into the same sandbox after its instance or image changes.
description: Save a directory from a Linux sandbox to your R2 bucket, and restore it into the same sandbox after its container or image changes.
pcx_content_type: how-to
sidebar:
order: 4
Expand All @@ -21,7 +21,7 @@ import {
WranglerConfig,
} from "~/components";

The `DirectoryBackup` class from `@cloudflare/sandbox` saves one directory as one object in your R2 bucket and restores it as ordinary files. R2 keeps each backup until you delete it. A container instance, the Linux virtual machine that your Durable Object starts, loses its files when it stops. You can restore a backup into a later instance, including one that runs a different image. For more information, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#deploys-keep-instances-running).
The `DirectoryBackup` class from `@cloudflare/sandbox` saves one directory as one object in your R2 bucket and restores it as ordinary files. R2 keeps each backup until you delete it. A container loses its files when it stops. You can restore a backup into a later container, including one that runs a different image. For more information, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#deploys-keep-instances-running).

In this example, the directory is a project in `/workspace/project`.

Expand All @@ -37,14 +37,15 @@ In this example, the directory is a project in `/workspace/project`.

1. Install the package:

<PackageManagers pkg="@cloudflare/sandbox" />
<PackageManagers pkg="@cloudflare/sandbox@1.0.1" />

2. Copy the helper binary into your image. If your project has no `Dockerfile`, create one in your project root:

```dockerfile title="Dockerfile"
FROM node:24-trixie-slim

COPY --from=docker.io/cloudflare/sandbox:1.0.1 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim
COPY --from=docker.io/cloudflare/sandbox:1.0.1 \
/usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim

RUN mkdir /workspace
CMD ["sleep", "infinity"]
Expand Down
4 changes: 2 additions & 2 deletions src/content/docs/sandbox/files/index.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Work with files in a sandbox
description: Move files in and out of a sandbox, keep a workspace after its instance stops, and share files through R2.
description: Move files in and out of a sandbox, keep a workspace after its container stops, and share files through R2.
pcx_content_type: navigation
sidebar:
order: 6
Expand All @@ -15,7 +15,7 @@ products:

The `Files` class from `@cloudflare/sandbox` moves files between your Worker and a running sandbox, and provides common file system operations. For more information, refer to [Move files in and out of a sandbox](/sandbox/files/manage-files/).

Each sandbox name reaches a [Durable Object](/durable-objects/), which starts a container instance when needed: a Linux virtual machine that runs your image. Stopping the instance deletes the files on its disk. For more information, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#snapshots-carry-files-to-the-next-instance).
Each sandbox name reaches a [Durable Object](/durable-objects/), which starts a container when needed. Stopping the container deletes the files on its disk. For more information, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#snapshots-carry-files-to-the-next-instance).

## Persistence

Expand Down
17 changes: 9 additions & 8 deletions src/content/docs/sandbox/files/manage-files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {

This guide streams an uploaded file into a sandbox, compresses it with `gzip`, and streams the compressed file back to the caller.

The `Files` class from `@cloudflare/sandbox` reads and writes files in a running [container instance](/sandbox/concepts/lifetime/), the Linux virtual machine that your Durable Object starts. [`exec()`](/containers/api/durable-object-container/#exec) runs the command. `Files` does not start the instance, so your Durable Object starts it before each file operation.
The `Files` class from `@cloudflare/sandbox` reads and writes files in a running [container](/sandbox/concepts/lifetime/). [`exec()`](/containers/api/durable-object-container/#exec) runs the command. `Files` does not start the container, so your Durable Object starts it before each file operation.

## Prerequisites

Expand All @@ -37,14 +37,15 @@ The `Files` class from `@cloudflare/sandbox` reads and writes files in a running

1. Install the package:

<PackageManagers pkg="@cloudflare/sandbox" />
<PackageManagers pkg="@cloudflare/sandbox@1.0.1" />

2. To give `Files` its helper binary, create a `Dockerfile` in the project root. If you already have one, add the `COPY` line to it:

```dockerfile title="Dockerfile"
FROM node:24-trixie-slim

COPY --from=docker.io/cloudflare/sandbox:1.0.1 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim
COPY --from=docker.io/cloudflare/sandbox:1.0.1 \
/usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim

RUN mkdir /workspace
CMD ["sleep", "infinity"]
Expand Down Expand Up @@ -77,7 +78,7 @@ The `Files` class from `@cloudflare/sandbox` reads and writes files in a running

The `workspace` key names the image. Your code starts it as `container.images.workspace`.

4. To start an instance before each file operation, replace the import and the `MyContainer` class in `src/index.ts` with a class that has a `startSandbox()` method. Keep the default export until step 6 replaces it:
4. To start a container before each file operation, replace the import and the `MyContainer` class in `src/index.ts` with a class that has a `startSandbox()` method. Keep the default export until step 6 replaces it:

<TypeScriptExample filename="src/index.ts">

Expand Down Expand Up @@ -111,7 +112,7 @@ The `Files` class from `@cloudflare/sandbox` reads and writes files in a running
}
}

// Files does not start an instance, so start one before each operation.
// Files does not start a container, so start one before each operation.
private async startSandbox(): Promise<void> {
if (!this.container.running) {
this.container.start({
Expand All @@ -126,7 +127,7 @@ The `Files` class from `@cloudflare/sandbox` reads and writes files in a running

</TypeScriptExample>

The constructor creates one `Files` object for the Durable Object, because `this.ctx.container` stays the same object for as long as the Durable Object runs. `startSandbox()` starts the `workspace` image when no instance is running, and sets the inactivity timeout after `start()`. For more information, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#the-timeout-does-not-survive-a-restart).
The constructor creates one `Files` object for the Durable Object, because `this.ctx.container` stays the same object for as long as the Durable Object runs. `startSandbox()` starts the `workspace` image when no container is running, and sets the inactivity timeout after `start()`. For more information, refer to [Sandbox lifetime](/sandbox/concepts/lifetime/#the-timeout-does-not-survive-a-restart).

5. To write the upload, run the command, and return the output file, add a `compress()` method to `MyContainer`:

Expand Down Expand Up @@ -213,7 +214,7 @@ The `Files` class from `@cloudflare/sandbox` reads and writes files in a running

## Remove output files

Compressed files stay in `/workspace` until the instance stops. To delete a file sooner, call `remove()` after the caller has read the response.
Compressed files stay in `/workspace` until the container stops. To delete a file sooner, call `remove()` after the caller has read the response.

For other file operations, such as listing a directory or renaming a file, refer to [Files API](/sandbox/reference/files/).

Expand Down Expand Up @@ -283,5 +284,5 @@ For more information, refer to [Sandbox security](/sandbox/concepts/security/#ev
## Related resources

- [Files API](/sandbox/reference/files/): every method, including `readDirectory()`, `rename()`, and `remove()`.
- [Save and restore a sandbox with snapshots](/sandbox/files/save-and-restore-a-workspace/): keep the files after the instance stops.
- [Save and restore a sandbox with snapshots](/sandbox/files/save-and-restore-a-workspace/): keep the files after the container stops.
- [Mount an R2 bucket](/sandbox/files/mount-an-r2-bucket/): write files that other systems read.
9 changes: 5 additions & 4 deletions src/content/docs/sandbox/files/mount-an-r2-bucket.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The `S3Mount` class from `@cloudflare/sandbox` mounts one prefix of a bucket as

1. Install the package:

<PackageManagers pkg="@cloudflare/sandbox" />
<PackageManagers pkg="@cloudflare/sandbox@1.0.1" />

2. Create a `Dockerfile` in your project root. It installs FUSE and `s3fs`, and copies `sandbox-shim`, the helper binary that `S3Mount` runs in the container:

Expand All @@ -47,7 +47,8 @@ The `S3Mount` class from `@cloudflare/sandbox` mounts one prefix of a bucket as
&& apt-get install -y --no-install-recommends ca-certificates fuse3 s3fs \
&& rm -rf /var/lib/apt/lists/*

COPY --from=docker.io/cloudflare/sandbox:1.0.1 /usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim
COPY --from=docker.io/cloudflare/sandbox:1.0.1 \
/usr/local/bin/sandbox-shim /usr/local/bin/sandbox-shim

CMD ["sleep", "infinity"]
```
Expand Down Expand Up @@ -177,7 +178,7 @@ The `S3Mount` class from `@cloudflare/sandbox` mounts one prefix of a bucket as

Any process in the sandbox can read, change, or delete every object under the prefix. Mount the narrowest prefix the job needs, and use `access: "read-only"` when the job only reads. The sandbox receives placeholder credentials, because `s3fs` requires a key pair. The mount works with `enableInternet: false`. For short-lived credentials, refer to [Credentials](/sandbox/reference/s3-mounts/#credentials).

Calling `mount()` again with the same settings reuses the existing mount. Each new mount adds an outbound intercept, and `unmount()` does not remove it. An instance supports a [limited number of intercepts](/containers/api/durable-object-container/#interceptoutboundhttp). Give each job its own sandbox name instead of mounting a new prefix in the same instance.
Calling `mount()` again with the same settings reuses the existing mount. Each new mount adds an outbound intercept, and `unmount()` does not remove it. A container supports a [limited number of intercepts](/containers/api/durable-object-container/#interceptoutboundhttp). Give each job its own sandbox name instead of mounting a new prefix in the same container.

7. Add a method that runs a command in the mounted directory:

Expand Down Expand Up @@ -321,5 +322,5 @@ Under `wrangler dev`, the container runs in Docker on your machine, and `S3Gatew

- [S3Mount API](/sandbox/reference/s3-mounts/): every option and error.
- [Artifact workspace example](https://github.com/cloudflare/sandbox-sdk/tree/main/examples/artifact-workspace): a deployable Worker that mounts a prefix for each sandbox and processes a file in it.
- [Save and restore a sandbox with snapshots](/sandbox/files/save-and-restore-a-workspace/): keep files on the sandbox disk between instances. Snapshots do not include mounted directories.
- [Save and restore a sandbox with snapshots](/sandbox/files/save-and-restore-a-workspace/): keep files on the sandbox disk between containers. Snapshots do not include mounted directories.
- [S3 API compatibility](/r2/api/s3/api/): the S3 operations that R2 supports.
Loading
Loading