sandbox-agent/docs/deploy/docker-sandbox.mdx
Nathan Flurry 1b2e65ec7f feat: add Docker Sandbox deployment support
Add example and documentation for deploying sandbox-agent inside Docker
Sandbox microVMs for enhanced isolation on macOS/Windows.

- Add examples/docker-sandbox/ with TypeScript example
- Add docs/deploy/docker-sandbox.mdx with setup guide using custom templates
- Update docs navigation to include Docker Sandbox
2026-02-07 11:48:19 -08:00

222 lines
6.9 KiB
Text

---
title: "Docker Sandbox"
description: "Run agents inside Docker Sandbox microVMs for enhanced isolation."
---
<Warning>
As of February 2026, Docker Sandbox microVMs are only available on macOS and Windows with Docker Desktop 4.58+. Linux users should use [regular Docker containers](/deploy/docker) or other sandbox providers. See [Docker Sandboxes Architecture](https://docs.docker.com/ai/sandboxes/architecture/) for details.
</Warning>
## Overview
[Docker Sandboxes](https://docs.docker.com/ai/sandboxes/) provide hypervisor-level isolation using lightweight microVMs. Each sandbox gets its own kernel, private Docker daemon, and isolated network for much stronger isolation than standard containers.
| | Docker Container | Docker Sandbox |
|--|------------------|----------------|
| **Security** | Shared kernel (namespaces) | Separate kernel (microVM) |
| **Untrusted code** | Not safe | Safe |
| **Port exposure** | Supported (`-p 3000:3000`) | Not supported |
| **Network access** | Direct HTTP | Via `docker sandbox exec` only |
| **Volumes** | Direct mount | Bidirectional file sync |
| **Platform** | Linux, macOS, Windows | macOS, Windows only |
### Why sandbox-agent inside Docker Sandbox?
Running sandbox-agent inside a Docker Sandbox provides:
- **Multiple sessions**: Manage multiple concurrent agent sessions within a single sandbox
- **Any coding agent**: Run any supported agent (Claude, Codex, OpenCode, Amp) through a unified API
- **Session persistence**: Sessions persist across interactions without recreating the sandbox
## Prerequisites
- Docker Desktop 4.58 or later
- macOS or Windows (experimental on Windows)
- `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` for the coding agents
## Setup
<Steps>
<Step title="Create Dockerfile">
Create a custom template with sandbox-agent as the main process:
```dockerfile
# Base template includes Ubuntu, Git, Docker CLI, Node.js, Python, Go
FROM docker/sandbox-templates:claude-code
USER root
# Install sandbox-agent
RUN curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh
# Pre-install agents
RUN sandbox-agent install-agent claude
RUN sandbox-agent install-agent codex
# Create wrapper: Docker Sandbox runs `claude` but we redirect to sandbox-agent
RUN mv /home/agent/.local/bin/claude /home/agent/.local/bin/claude-real \
&& printf '#!/bin/bash\nexec sandbox-agent server --no-token --host 0.0.0.0\n' \
> /home/agent/.local/bin/claude \
&& chmod +x /home/agent/.local/bin/claude
USER agent
```
<Note>
Docker Sandbox requires an agent argument (`claude`, `codex`, etc.) and runs that agent as the main process. The wrapper script intercepts the `claude` command and runs sandbox-agent server instead.
</Note>
</Step>
<Step title="Build the template">
```bash
docker build -t sandbox-agent-template:latest .
```
</Step>
<Step title="Run sandbox">
```bash
docker sandbox run \
--load-local-template \
-t sandbox-agent-template:latest \
--name my-sandbox \
claude ~/my-project
```
The sandbox-agent server starts automatically as the main process.
</Step>
<Step title="Interact with the server">
In another terminal, use `docker sandbox exec` to interact:
```bash
# Create a session
docker sandbox exec my-sandbox \
sandbox-agent api sessions create my-session --agent claude
# Send a message (pass API key via -e)
docker sandbox exec -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" my-sandbox \
sandbox-agent api sessions send-message my-session \
--message "Summarize this repository"
# Stream events
docker sandbox exec my-sandbox \
sandbox-agent api sessions events my-session
```
</Step>
<Step title="Clean up">
```bash
docker sandbox stop my-sandbox
docker sandbox rm my-sandbox
```
</Step>
</Steps>
## TypeScript Example
```typescript
import { execSync, spawn, spawnSync } from "node:child_process";
const SANDBOX_NAME = "my-agent-sandbox";
const TEMPLATE = "sandbox-agent-template:latest";
function exec(cmd: string): string {
return execSync(cmd, { encoding: "utf-8" }).trim();
}
function sandboxExec(cmd: string, env?: Record<string, string>): string {
const envFlags = env
? Object.entries(env).flatMap(([k, v]) => ["-e", `${k}=${v}`])
: [];
const args = ["sandbox", "exec", ...envFlags, SANDBOX_NAME, "sh", "-c", cmd];
const result = spawnSync("docker", args, { encoding: "utf-8" });
return result.stdout?.trim() ?? "";
}
// Run sandbox with custom template (sandbox-agent starts as main process)
spawn("docker", [
"sandbox", "run",
"--load-local-template", "-t", TEMPLATE,
"--name", SANDBOX_NAME,
"claude", process.cwd()
], { detached: true, stdio: "ignore" }).unref();
// Wait for server to start
await new Promise((r) => setTimeout(r, 5000));
// Create a session
sandboxExec("sandbox-agent api sessions create my-session --agent claude");
// Send a message (pass API key via exec -e flag)
sandboxExec(
"sandbox-agent api sessions send-message my-session --message 'Hello'",
{ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! }
);
// Get events
const output = sandboxExec("sandbox-agent api sessions events my-session");
console.log(output);
// Cleanup
exec(`docker sandbox stop ${SANDBOX_NAME}`);
exec(`docker sandbox rm ${SANDBOX_NAME}`);
```
## Sandbox Commands Reference
```bash
# List all sandboxes
docker sandbox ls
# Create a sandbox with custom template
docker sandbox create --load-local-template -t <image> --name <name> AGENT WORKSPACE
# Run agent interactively (creates sandbox if needed)
docker sandbox run claude ~/my-project
# Execute command in sandbox
docker sandbox exec <name> <command>
# Execute with environment variables
docker sandbox exec -e VAR=value <name> <command>
# Run command in background
docker sandbox exec -d <name> <command>
# Interactive shell
docker sandbox exec -it <name> bash
# Save sandbox as template
docker sandbox save <name> my-template:v1
# Stop sandbox (without removing)
docker sandbox stop <name>
# Remove sandbox
docker sandbox rm <name>
```
### Create Options
| Flag | Description |
|------|-------------|
| `--name` | Custom name for the sandbox |
| `-t, --template <image>` | Use custom Docker image as base |
| `--load-local-template` | Use image from local Docker daemon |
| `-q, --quiet` | Suppress verbose output |
### Exec Options
| Flag | Description |
|------|-------------|
| `-e VAR=value` | Set environment variable for this command |
| `-d, --detach` | Run command in background |
| `-i, --interactive` | Keep STDIN open |
| `-t, --tty` | Allocate a pseudo-TTY |
## Further Reading
- [Docker Sandboxes Documentation](https://docs.docker.com/ai/sandboxes/)
- [Docker Sandboxes Templates](https://docs.docker.com/ai/sandboxes/templates/)
- [Docker Sandboxes Architecture](https://docs.docker.com/ai/sandboxes/architecture/)
- [Regular Docker Deployment](/deploy/docker) (for HTTP server access)