SecondBrain/howto/devcontainer-sandbox-setup.md

3.5 KiB

type title summary tags scope last_updated date update_note related source
howto Set Up a DevContainer Sandbox for Autonomous Claude Code How to run Claude Code in `--dangerously-skip-permissions` mode safely, by isolating it inside a Docker devcontainer instead of the host machine.
type/howto
domain/agent-orchestration
tool/docker
tool/claude-code
global 2026-07-13 2026-07-13 experience-driven
design-mode/docs/devcontainer-guide.md

Set Up a DevContainer Sandbox for Autonomous Claude Code

Opening

Reach for this when you want to let Claude Code run unsupervised with --dangerously-skip-permissions (fully autonomous, no per-action confirmation) but don't want it to have that power directly against your host filesystem — a Docker container gives it a disposable, reproducible environment instead.

Prerequisites

  • Docker + Docker Compose installed on the host
  • A docker-compose.yml defining the sandbox service, running as a non-root user (root is refused by --dangerously-skip-permissions)
  • ANTHROPIC_API_KEY available to export or place in a .env file
  • Dev tooling baked into the image: git, gh, curl/wget, python3, nodejs (for the Claude Code runtime), ripgrep, jq at minimum

Steps

Step 1: Build and start the sandbox

docker compose up -d --build

Builds the image (if changed) and starts the container in the background.

Step 2: Export your API key before first use

export ANTHROPIC_API_KEY=sk-ant-...
docker compose up -d --build

Or place ANTHROPIC_API_KEY=sk-ant-... in a .env file next to the compose file — either works, but the key must be present before the container starts if Claude Code will authenticate via env var.

Step 3: Enter the sandbox and run Claude Code unsupervised

docker exec -it <container-name> bash
claude --dangerously-skip-permissions

Runs as the container's non-root user. Because the blast radius is the container's filesystem, not the host's, autonomous mode is safe to use here in a way it would not be run directly on the host.

Step 4: Stop or reset when done

docker compose down       # stop, keep persisted home volume
docker compose down -v    # stop AND wipe the persisted home volume (full reset)

Verification

docker exec -it <container-name> bash drops you into a shell as the non-root user; whoami should not return root, and claude --version should succeed inside the container.

Gotchas

  • claude --dangerously-skip-permissions refuses to run as root — the container user must be non-root (with passwordless sudo if you need to install packages ad hoc); running the container as root will silently block autonomous mode.
  • Mounting ~/.claude/ read-write shares host state into the sandbox — this carries over slash commands, settings, and MCP config, but also lets the container modify host ~/.claude/ files. Mount it :ro if you want the container's autonomy contained to the container's own filesystem only.
  • network_mode: host skips Docker's port mapping — services in the container bind directly to host ports; if you instead use bridge networking you must add explicit port mappings or exposed ports won't be reachable.
  • A named volume for the home directory persists Claude Code auth and shell state across container restartsdocker compose down alone preserves it; only -v wipes it. Use the volume when you want to avoid re-authenticating every session, and -v deliberately when you want a truly clean environment.