Docker
Run agent tasks in isolated Docker containers
The Docker sandbox provider runs each agent task in an isolated Docker container, providing better security and consistent environments.
Overview
| Feature | Value |
|---|---|
| Isolation | Container-level |
| Setup | Docker required |
| Performance | Fast with sandbox image |
| Use case | Multi-user, untrusted code |
Requirements
- Docker installed and running
- Docker daemon accessible to the Sesame process
- Sufficient disk space for container images (~3GB for the sandbox image)
Configuration
# Enable Docker provider
SANDBOX_PROVIDER=docker
# Optional: customize settings
TASK_DIR_BASE=/tmp/sesame
DOCKER_SANDBOX_IMAGE=ghcr.io/jakejarvis/sesame-sandbox:latestOfficial Sandbox Image
Sesame provides an official sandbox image pre-loaded with everything needed for fast task execution:
# Pull from GitHub Container Registry (recommended)
docker pull ghcr.io/jakejarvis/sesame-sandbox:latest
# Or from Docker Hub
docker pull jakejarvis/sesame-sandbox:latestWhat's Included
The sandbox image comes with:
Runtimes (via mise):
| Runtime | Versions | Default |
|---|---|---|
| Node.js | 20, 22, 24 | 24 (LTS) |
| Python | 3.12, 3.13, 3.14 | 3.14 |
| Go | latest | latest |
| Rust | latest | latest |
| Ruby | latest | latest |
| Bun | latest | latest |
AI Agent CLIs:
| Agent | CLI | Pre-installed |
|---|---|---|
| Claude Code | claude | Yes |
| Codex | codex | Yes |
| Copilot | copilot | Yes |
| Gemini | gemini | Yes |
| OpenCode | opencode | Yes |
Dev Tools:
- git, git-lfs
- gh (GitHub CLI)
- curl, wget, jq
- Build essentials (gcc, make, etc.)
Benefits
| Without Sandbox Image | With Sandbox Image |
|---|---|
| Downloads mise each task | mise pre-installed |
| Downloads runtimes on demand | Common runtimes pre-cached |
| Installs agent CLI per task | Agent CLIs ready to use |
| Slower task startup | Fast task startup |
Image Tags
| Tag | Description |
|---|---|
latest | Most recent stable build |
YYYYMMDD | Weekly builds (e.g., 20260203) |
X.Y.Z | Semantic version releases |
The image is automatically rebuilt weekly to pick up runtime updates.
How It Works
-
Container Creation: Each task gets its own container
docker run -d \ --name sesame-sandbox-{taskId} \ -v /tmp/sesame/{taskId}/project:/workspace \ -w /workspace \ -p {hostPort}:3000 \ ghcr.io/jakejarvis/sesame-sandbox:latest \ tail -f /dev/null -
Mise Bootstrap: Links to pre-installed mise and shims
# With sandbox image: instant (symlinks to /opt/mise) # With custom image: downloads mise binary -
Runtime Setup: Installs any additional versions needed
# Reads .nvmrc, .python-version, .tool-versions, etc. mise install # Fast if version is pre-cached mise prepare # Installs project dependencies -
Agent Ready: With the sandbox image, agents are pre-installed
# No installation needed - claude, codex, copilot, gemini, opencode ready -
Volume Mounting: The project directory is mounted into the container at
/workspace -
Command Execution: Commands run via
docker execdocker exec sesame-sandbox-{taskId} npm install -
Port Mapping: Container port 3000 is mapped to a random available host port
-
Cleanup: Container is stopped and removed when the task completes
Agent Availability
With the official sandbox image, all agent CLIs are pre-installed and ready to use immediately:
| Agent | CLI | Status |
|---|---|---|
| Claude Code | claude | Pre-installed |
| Codex | codex | Pre-installed |
| Copilot | copilot | Pre-installed |
| Gemini | gemini | Pre-installed |
| OpenCode | opencode | Pre-installed |
If you use a custom base image, Sesame will automatically install the selected agent's CLI at runtime:
| Agent | Installation Command |
|---|---|
| Claude Code | npm install -g @anthropic-ai/claude-code |
| Codex | npm install -g @openai/codex |
| Copilot | npm install -g @github/copilot |
| Gemini | npm install -g @google/gemini-cli |
| OpenCode | npm install -g opencode-ai |
Using the official sandbox image is recommended for production deployments to minimize task startup time.
Advantages
- Isolation: Each task runs in its own container with no access to host filesystem (except mounted volume)
- Consistent environment: Same base image regardless of host configuration
- Security: Better protection against malicious code
- Reproducibility: Tasks run in identical environments
Limitations
- Startup overhead: Container creation adds 2-5 seconds to task startup
- Resource usage: Each container consumes memory and disk space
- Docker dependency: Requires Docker to be installed and running
- Networking complexity: Port mapping required for preview URLs
Environment Variables
| Variable | Default | Description |
|---|---|---|
SANDBOX_PROVIDER | local | Set to docker to enable |
TASK_DIR_BASE | /tmp/sesame | Base directory for mounted volumes |
DOCKER_SANDBOX_IMAGE | ghcr.io/jakejarvis/sesame-sandbox:latest | Base Docker image |
DOCKER_HOST | (system default) | Docker daemon socket (e.g., tcp://proxy:2375) |
DOCKER_TLS_VERIFY | (unset) | Enable TLS verification for remote Docker |
DOCKER_CERT_PATH | (unset) | Path to TLS certificates for remote Docker |
Custom Images
Extending the Official Image
For most customizations, extend the official sandbox image:
# Dockerfile.custom
FROM ghcr.io/jakejarvis/sesame-sandbox:latest
# Add more Node.js versions
RUN mise install node@16
# Add Java
RUN mise install java@21 && mise reshim
# Add custom npm packages
RUN npm install -g your-custom-tool
# Add system packages
RUN apt-get update && apt-get install -y \
your-package \
&& rm -rf /var/lib/apt/lists/*Build and use:
docker build -t my-sandbox -f Dockerfile.custom .
DOCKER_SANDBOX_IMAGE=my-sandboxBuilding from Scratch
If you need a minimal image without pre-installed runtimes:
# Dockerfile.minimal
FROM debian:trixie-slim
# Install essentials
RUN apt-get update && apt-get install -y \
git curl ca-certificates build-essential \
&& rm -rf /var/lib/apt/lists/*
# Install mise
ENV MISE_VERSION=2026.2.2
RUN curl -fsSL "https://github.com/jdx/mise/releases/download/v${MISE_VERSION}/mise-v${MISE_VERSION}-linux-x64.tar.gz" \
| tar -xz -C /usr/local --strip-components=1
# Install just what you need
RUN mise install node@24 && mise use --global node@24 && mise reshim
WORKDIR /workspaceCustom images without pre-installed agents will have slower task startup as agents must be installed at runtime.
Networking
The Docker provider uses bridge networking with explicit port mapping:
- Container port 3000 is mapped to a random available host port (10000-65000)
- Preview URLs use the mapped host port:
http://localhost:{hostPort} - Additional ports can be exposed by customizing the provider
Resource Limits
The default configuration doesn't set resource limits. Consider extending the provider to add:
# Example limits (not yet configurable via env vars)
--memory="2g"
--cpus="2"Troubleshooting
"Docker is required but not available"
This error means Docker isn't running or accessible:
- Check Docker is installed:
docker --version - Check Docker daemon is running:
docker ps - On Linux, ensure the user is in the
dockergroup:sudo usermod -aG docker $USER
Container Already Exists
If a container with the same name exists, it will be automatically removed before creating a new one. If you see issues:
# List Sesame containers
docker ps -a | grep sesame-sandbox
# Remove stuck containers
docker rm -f $(docker ps -a -q --filter "name=sesame-sandbox")Port Conflicts
The provider automatically finds available ports. If you consistently see port issues:
- Check for orphaned containers using ports
- Ensure the port range (10000-65000) isn't blocked by firewall
- Check other services aren't consuming all available ports
Volume Permission Issues
If you see permission errors accessing mounted files:
- Check host directory permissions:
ls -la /tmp/sesame/ - The container runs as root by default, which should have access
- On SELinux systems, you may need
:zor:Zvolume options
Cleanup Issues
Containers should be removed automatically. If orphaned containers accumulate:
# Remove all Sesame sandbox containers
docker rm -f $(docker ps -a -q --filter "name=sesame-sandbox")
# Remove unused images
docker image pruneHost Docker Socket
When running Sesame in Docker, you can use the host's Docker daemon instead of Docker-in-Docker (DinD). This is the recommended approach.
Why Use the Host Docker Socket?
| Docker-in-Docker (DinD) | Host Docker Socket |
|---|---|
| Requires privileged mode | No privileged mode needed |
| Nested containers add latency | Direct access, better performance |
| Storage driver complexity | Uses host's storage driver |
| Caching doesn't persist across restarts | Image cache shared with host |
| Complete isolation from host | Sandbox containers visible on host |
Configuration Options
Option 1: Direct Socket Mount
The simplest approach - mount the Docker socket directly:
services:
sesame:
environment:
- SANDBOX_PROVIDER=docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock
# IMPORTANT: Use bind mount for sandboxes so host Docker can access them
- ./sandboxes:/app/sandboxesDirect socket access grants full Docker API control. Any process in the container can create privileged containers, mount host filesystems, or access other containers. Only use this if you trust all code running in Sesame.
Option 2: Docker Socket Proxy (Recommended)
Use docker-socket-proxy for fine-grained access control:
services:
sesame:
environment:
- SANDBOX_PROVIDER=docker
- DOCKER_HOST=tcp://docker-socket-proxy:2375
volumes:
- ./sandboxes:/app/sandboxes
depends_on:
- docker-socket-proxy
docker-socket-proxy:
image: tecnativa/docker-socket-proxy:latest
environment:
# Only enable required endpoints
- CONTAINERS=1
- IMAGES=1
- EXEC=1
- VERSION=1
- POST=1
# Keep everything else disabled
- AUTH=0
- BUILD=0
- NETWORKS=0
- VOLUMES=0
- SWARM=0
volumes:
- /var/run/docker.sock:/var/run/docker.sock:roA complete example is available in docker-compose.socket-proxy.yml.
Option 3: Remote Docker Host
Connect to a remote Docker daemon over TCP:
DOCKER_HOST=tcp://docker-host.example.com:2375
# Or with TLS:
DOCKER_HOST=tcp://docker-host.example.com:2376
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/path/to/certsVolume Mount Considerations
When using the host Docker socket, sandbox containers are created on the host, not inside the Sesame container. This means:
- Sandbox directories must be accessible from both Sesame and the host
- Use bind mounts instead of named volumes for the sandboxes directory
- Paths must match between what Sesame sees and what the host sees
services:
sesame:
environment:
# Tell Sesame where sandboxes are (from its perspective)
- TASK_DIR_BASE=/app/sandboxes
volumes:
# Bind mount so the path is consistent
- ./sandboxes:/app/sandboxesIf Sesame runs with TASK_DIR_BASE=/app/sandboxes and you use a named volume, the host Docker daemon won't be able to find the project files to mount into sandbox containers.
Security Considerations
While Docker provides better isolation than the local provider:
- Volume mounts expose the project directory to the container
- Network access is not restricted by default
- Root in container - processes run as root inside the container
Socket-specific risks:
- Container escape: With socket access, a compromised process could create a privileged container and access the host
- Data exfiltration: Access to other containers' filesystems and networks
- Resource exhaustion: Ability to spawn unlimited containers
Mitigations:
- Use docker-socket-proxy to limit API access
- Run Sesame with
--read-onlywhere possible - Use Docker user namespaces
- Consider network isolation with custom Docker networks
- Set resource limits to prevent DoS
- Regularly audit running containers
For maximum security:
- Use read-only volume mounts where possible
- Consider network isolation with custom Docker networks
- Run containers as non-root users
- Set resource limits to prevent DoS