Skip to content
Open
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
107 changes: 105 additions & 2 deletions src/content/docs/sandbox/configuration/dockerfile.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ sidebar:

Customize the sandbox container image with your own packages, tools, and configurations by extending the base runtime image.

:::note
Looking to add sandbox capabilities to an existing Docker image? See the [Standalone binary](/sandbox/configuration/standalone-binary/) pattern for an alternative approach that does not require extending the base image.
:::

## Base image

The Sandbox SDK uses a Ubuntu-based Linux container with Python, Node.js (via Bun), and common development tools pre-installed:
Expand Down Expand Up @@ -70,7 +74,101 @@ Update `wrangler.jsonc` to reference your Dockerfile:

When you run `wrangler dev` or `wrangler deploy`, Wrangler automatically builds your Docker image and pushes it to Cloudflare's container registry. You don't need to manually build or publish images.

## Custom startup scripts
## Standalone binary for arbitrary base images

Add Sandbox capabilities to any Docker image by copying the `/sandbox` binary from the official image. This allows you to use your own base image (Alpine, Debian, custom images) instead of extending the Ubuntu-based Sandbox image.

```dockerfile title="Dockerfile"
FROM node:20-alpine

# Required: install dependencies
RUN apk add --no-cache bash file

COPY --from=docker.io/cloudflare/sandbox:0.3.3 /container-server/sandbox /sandbox

ENTRYPOINT ["/sandbox"]
```

The `/sandbox` binary:
- Starts the HTTP API server (listening on port 3000)
- Executes any `CMD` you provide as a child process
- Forwards signals (SIGTERM, SIGINT) to the child process
- Exits when the child process exits

### With custom startup command

```dockerfile title="Dockerfile"
FROM python:3.11-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
bash file git \
&& rm -rf /var/lib/apt/lists/*

COPY --from=docker.io/cloudflare/sandbox:0.3.3 /container-server/sandbox /sandbox
COPY startup.sh /startup.sh
RUN chmod +x /startup.sh

ENTRYPOINT ["/sandbox"]
CMD ["/startup.sh"]
```

```bash title="startup.sh"
#!/bin/bash
set -e

# Start background services
redis-server --daemonize yes

# Start your application
exec python /workspace/app.py
```

:::note
When using the standalone binary pattern, your startup script should NOT call `exec bun /container-server/dist/index.js`. The binary automatically starts the API server before running your CMD.
:::

### Required dependencies

The standalone binary requires these system packages:

| Package | Required For | Install Command |
| --- | --- | --- |
| `bash` | Core requirement | Usually pre-installed |
| `file` | `readFile()`, `writeFile()`, any file operation | `apt-get install file` or `apk add file` |
| `git` | `gitCheckout()`, `listBranches()` | `apt-get install git` or `apk add git` |

Most base images include `bash`. You typically only need to install `file` and `git` (if using git operations).

**What works without extra dependencies:**
- `exec()` - Run shell commands
- `startProcess()` - Background processes
- `exposePort()` - Expose services

**Limitations:**
- Code interpreter (`runCode()`) requires Python/Node.js executors not included in the standalone binary. Use the official Sandbox images if you need code execution features.

### Accessing the binary

**From Docker image:**

```bash
docker run --rm docker.io/cloudflare/sandbox:0.3.3 cat /container-server/sandbox > sandbox
chmod +x sandbox
```

**From GitHub releases:**

```bash
gh release download @cloudflare/sandbox@0.3.3 -p sandbox-linux-x64
mv sandbox-linux-x64 sandbox
chmod +x sandbox
```

## Custom startup scripts (legacy)

:::note
If you're building a new project, prefer the [standalone binary pattern](/sandbox/configuration/dockerfile/#standalone-binary-for-arbitrary-base-images) with `ENTRYPOINT ["/sandbox"]` and `CMD`. The method below is maintained for backwards compatibility.
:::

Run services automatically when the container starts by creating a custom startup script:

Expand All @@ -93,7 +191,11 @@ node /workspace/my-app.js &
exec bun /container-server/dist/index.js
```

Your startup script must end with `exec bun /container-server/dist/index.js` to start the SDK's control plane.
Your startup script must end with `exec bun /container-server/dist/index.js` to start the SDK control plane.

:::note
The [Standalone binary](/sandbox/configuration/standalone-binary/) pattern provides a simpler approach for startup commands - you can specify CMD directly in your Dockerfile without needing to call the control plane explicitly.
:::

### Multiple services

Expand All @@ -110,6 +212,7 @@ exec bun /container-server/dist/index.js

## Related resources

- [Standalone binary](/sandbox/configuration/standalone-binary/) - Add sandbox to arbitrary Docker images
- [Image Management](/containers/platform-details/image-management/) - Building and pushing images to Cloudflare\'s registry
- [Wrangler configuration](/sandbox/configuration/wrangler/) - Using custom images in wrangler.jsonc
- [Docker documentation](https://docs.docker.com/reference/dockerfile/) - Complete Dockerfile syntax
Expand Down
8 changes: 8 additions & 0 deletions src/content/docs/sandbox/configuration/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ Configure your Sandbox SDK deployment with Wrangler, customize container images,
configurations.
</LinkTitleCard>

<LinkTitleCard
title="Standalone binary"
href="/sandbox/configuration/standalone-binary/"
icon="wrench"
>
Add sandbox capabilities to any Docker image using the standalone binary.
</LinkTitleCard>

<LinkTitleCard
title="Environment variables"
href="/sandbox/configuration/environment-variables/"
Expand Down
238 changes: 238 additions & 0 deletions src/content/docs/sandbox/configuration/standalone-binary.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
---
title: Standalone binary
pcx_content_type: configuration
sidebar:
order: 3
---

Add Cloudflare Sandbox capabilities to any Docker image using the standalone `/sandbox` binary.

## Overview

The standalone binary pattern allows you to add sandbox functionality to arbitrary Docker images without extending the official base image. This is useful when you:

- Already have a production-ready Docker image
- Need to minimize image size by starting from a minimal base (alpine, distroless, etc.)
- Want full control over the base operating system and installed packages

The `/sandbox` binary is a self-contained executable that:

1. Starts the HTTP API server on port 3000
2. Executes any user-provided CMD as a child process
3. Forwards signals for graceful shutdown

## Basic usage

Copy the binary from the official image and use it as your entrypoint:

```dockerfile
FROM node:20-slim

# Required: install 'file' for SDK file operations
RUN apt-get update && apt-get install -y --no-install-recommends file \
&& rm -rf /var/lib/apt/lists/*

COPY --from=cloudflare/sandbox:latest /container-server/sandbox /sandbox

ENTRYPOINT ["/sandbox"]
```

Update your wrangler configuration to use the custom Dockerfile:

```jsonc title="wrangler.jsonc"
{
"containers": [
{
"class_name": "Sandbox",
"image": "./Dockerfile"
}
]
}
```

:::caution[Version synchronization required]
Always match the Docker image version to your npm package version. If you are using `@cloudflare/sandbox@0.3.3`, copy the binary from `cloudflare/sandbox:0.3.3`.

```dockerfile
COPY --from=cloudflare/sandbox:0.3.3 /container-server/sandbox /sandbox
```

See [Version compatibility](/sandbox/concepts/sandboxes/#version-compatibility) for troubleshooting version mismatch warnings.
:::

## Optional startup command

The binary supports an optional CMD that runs after the API server starts:

```dockerfile
FROM python:3.11-slim

RUN apt-get update && apt-get install -y --no-install-recommends file bash \
&& rm -rf /var/lib/apt/lists/*

COPY --from=cloudflare/sandbox:latest /container-server/sandbox /sandbox
COPY startup.sh /workspace/startup.sh
RUN chmod +x /workspace/startup.sh

ENTRYPOINT ["/sandbox"]
CMD ["/workspace/startup.sh"]
```

```bash title="startup.sh"
#!/bin/bash

# Start background services
redis-server --daemonize yes

# Start application server
python /workspace/app.py &
```

The binary forwards signals (SIGTERM, SIGINT) to the child process for graceful shutdown.

## Required dependencies

| Dependency | Required for | Install command |
| --- | --- | --- |
| `file` | File operations (`readFile()`, `writeFile()`) | `apt-get install file` |
| `git` | Git operations (`gitCheckout()`, `listBranches()`) | `apt-get install git` |
| `bash` | Core functionality (shell commands) | Usually pre-installed |

Most base images (node:slim, python:slim, ubuntu) include `bash` but not `file` or `git`.

### Minimal example

```dockerfile
FROM node:20-slim

# Install only what you need
RUN apt-get update && apt-get install -y --no-install-recommends \
file \
git \
&& rm -rf /var/lib/apt/lists/*

COPY --from=cloudflare/sandbox:latest /container-server/sandbox /sandbox

ENTRYPOINT ["/sandbox"]
```

## What works without extra dependencies

- `exec()` - Run shell commands
- `startProcess()` - Manage background processes
- `exposePort()` - Expose services via preview URLs

## Code interpreter limitations

The standalone binary does not include Python or Node.js executors required for code interpreter functionality. If you need `runCode()`, use the official base image instead:

```dockerfile
FROM cloudflare/sandbox:latest

# Add your customizations
RUN pip install scikit-learn
```

Alternatively, install Python or Node.js in your custom image:

```dockerfile
FROM ubuntu:22.04

RUN apt-get update && apt-get install -y python3 nodejs file bash

COPY --from=cloudflare/sandbox:latest /container-server/sandbox /sandbox

ENTRYPOINT ["/sandbox"]
```

## Troubleshooting

### Failed to detect MIME type

**Error message:**

```
Failed to detect MIME type
```

**Solution:** Install the `file` package:

```dockerfile
RUN apt-get update && apt-get install -y file
```

### Git command not found

**Error message:**

```
git: command not found
```

**Solution:** Install git (only needed if using git operations):

```dockerfile
RUN apt-get update && apt-get install -y git
```

### Commands hang or timeout

**Symptom:** Commands never complete, timeout errors

**Solution:** Ensure `bash` is available at `/bin/bash`. Most distributions include bash by default, but minimal images (alpine, distroless) may not.

```dockerfile
# For Alpine Linux
RUN apk add bash

# For Debian/Ubuntu
RUN apt-get update && apt-get install -y bash
```

## Download the binary

### From Docker image

Extract the binary from a running container:

```bash
docker run --rm cloudflare/sandbox:latest cat /container-server/sandbox > sandbox
chmod +x sandbox
```

### From GitHub releases

Download from GitHub releases (requires GitHub CLI):

```bash
gh release download @cloudflare/sandbox@0.3.3 -p sandbox-linux-x64
chmod +x sandbox-linux-x64
```

### From PR artifacts

Preview versions are available as artifacts in pull request builds:

```bash
gh run download <RUN_ID> -n sandbox-binary
```

## Backwards compatibility

The standalone binary maintains compatibility with existing custom startup scripts. If your script calls `bun /container-server/dist/index.js`, it detects the running server and exits cleanly:

```bash title="legacy-startup.sh"
#!/bin/bash

# Your services
redis-server --daemonize yes

# This is now a no-op if using /sandbox entrypoint
exec bun /container-server/dist/index.js
```

## Related resources

- [Dockerfile reference](/sandbox/configuration/dockerfile/) - Extending the official base image
- [Container concepts](/sandbox/concepts/containers/) - Understanding the runtime environment
- [Environment variables](/sandbox/configuration/environment-variables/) - Configuring the runtime
Loading