Sandbox coding agents inside Docker containers.
  • TypeScript 96.5%
  • Dockerfile 2.3%
  • Shell 1.1%
Find a file
2026-03-12 18:57:03 -07:00
bin feat: add user mapping and container path expansion for Docker configuration 2026-03-11 13:33:34 -07:00
docs chore: final wiring and polish for v1 2026-03-11 00:43:57 -07:00
images feat: reorganize Dockerfile to install Playwright and MCP server globally 2026-03-12 18:57:03 -07:00
scripts chore: add integration test script 2026-03-10 20:29:52 -07:00
src feat: add SSH host key pre-seeding and compatibility mounts for bind paths in Docker 2026-03-11 21:31:28 -07:00
tests feat: add SSH host key pre-seeding and compatibility mounts for bind paths in Docker 2026-03-11 21:31:28 -07:00
.gitignore chore: scaffold codebox project 2026-03-10 20:25:04 -07:00
package-lock.json 0.2.0 2026-03-11 23:33:00 -07:00
package.json 0.2.0 2026-03-11 23:33:00 -07:00
README.md feat: add instructions for detaching from containers without stopping the agent 2026-03-12 00:00:00 -07:00
tsconfig.json chore: scaffold codebox project 2026-03-10 20:25:04 -07:00
vitest.config.ts chore: scaffold codebox project 2026-03-10 20:25:04 -07:00

Codebox

Sandbox coding agents inside Docker containers. Run agents like Claude Code in their most permissive mode without risking your host system.

Codebox is a thin wrapper around Docker — it builds the right docker run command from config and flags, manages container lifecycle, and forwards stdio.

Quick Start

# Build and install
npm install
npm run build
npm link

# Build the Docker image
docker build -t codebox/claude-code:latest images/claude-code/

# Create config (optional)
mkdir -p ~/.config/codebox
cat > ~/.config/codebox/codebox.json << 'EOF'
{
  "extra-binds": {
    "~/.claude": "~/.claude"
  },
  "environment": {
    "ANTHROPIC_API_KEY": "$ANTHROPIC_API_KEY"
  }
}
EOF

# Launch a sandbox
cd your-project/
codebox

Commands

Command Description
codebox / codebox start Launch a sandbox in the current directory
codebox list / codebox ls Show all codebox containers (running + stopped)
codebox attach <name> Re-attach to an existing container
codebox stop <name> Stop a running container
codebox rm <name> Remove a stopped container

Start Flags

--no-tty              Headless mode — stdin/stdout piped, no pseudo-TTY
--existing <behavior> Conflict behavior when a container already exists:
                        reattach — attach to existing (start if stopped)
                        replace  — stop & remove old, launch fresh
                        new      — launch additional container
-- <docker-args...>   Passthrough args for docker run

If --existing is omitted and a container already exists for the workspace, codebox prompts interactively. In headless mode (--no-tty), it errors instead of prompting.

Configuration

Codebox loads configuration from two optional files, merged together:

  1. System: ~/.config/codebox/codebox.json
  2. Project: .codebox.json in the current working directory (overrides system config)

For object fields (extra-binds, environment), project values are merged with system values. For scalar fields (image, user) and arrays (extra-args), project values replace system values.

{
  "image": "codebox/claude-code:latest",
  "user": "1000:1000",
  "extra-binds": {
    "~/.claude": "~/.claude"
  },
  "environment": {
    "ANTHROPIC_API_KEY": "$ANTHROPIC_API_KEY"
  },
  "extra-args": ["--cpus=2", "--memory=4g"]
}
Key Description Default
image Docker image to use codebox/claude-code:latest
user Container user (UID:GID or "root"). If omitted, uses host UID:GID Host UID:GID
extra-binds Host:container path pairs (~ expanded on both sides) {}
environment Env vars for the container (values starting with $ resolve from host env) {}
extra-args Additional arguments passed to docker run []

The workspace bind ($PWD:/workspace) is always applied implicitly. CLI passthrough args (-- <args>) take precedence over extra-args from config.

How It Works

When you run codebox, it:

  1. Checks Docker is available
  2. Loads config from ~/.config/codebox/codebox.json and .codebox.json (if they exist)
  3. Checks for existing containers for this workspace (via Docker labels)
  4. Pulls the image if not available locally
  5. Runs docker run with the right flags: workspace mount, network host, env vars, bind mounts
  6. Forwards stdio and signals (Ctrl+C works naturally)

Containers are named codebox-<dirname> where the directory name is lowercased and non-alphanumeric characters are replaced with hyphens (e.g., My_Projectcodebox-my-project). When using --existing=new, a suffix is appended (-2, -3, etc.). Containers persist after exit — use codebox list, codebox stop, and codebox rm to manage them.

Detaching Without Stopping the Agent

While attached to a container (via codebox start or codebox attach), press Ctrl+P then Ctrl+Q to detach your terminal without stopping the agent. The container keeps running in the background and you can reconnect later with codebox attach <name>.

Headless / Programmatic Mode

codebox start --no-tty --existing=replace

Runs without a pseudo-TTY — stdin/stdout are piped for programmatic control. Combine with --existing=replace for fully non-interactive automation. The outer process talks directly to the inner agent over stdio.

Development

npm install
npm run build          # Compile TypeScript
npm test               # Run tests
npm run test:watch     # Watch mode

Requirements

  • Node.js 18+
  • Docker