--- type: howto title: Set Up a DevContainer Sandbox for Autonomous Claude Code summary: How to run Claude Code in `--dangerously-skip-permissions` mode safely, by isolating it inside a Docker devcontainer instead of the host machine. tags: - type/howto - domain/agent-orchestration - tool/docker - tool/claude-code scope: global last_updated: 2026-07-13 date: 2026-07-13 update_note: experience-driven related: [] source: design-mode --- # 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 ```bash 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 ```bash 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 ```bash docker exec -it 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 ```bash 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 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 restarts** — `docker 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.