Running Claude Code in Docker Sandboxes
You gave an AI agent the ability to run arbitrary shell commands on your machine. Congratulations. Now you need a way to make sure it doesn't rm -rf your home directory or email your SSH keys to a stranger.
Docker Sandboxes solve this by running Claude Code inside a microVM: a lightweight virtual machine that looks like your project directory but has no access to the rest of your system. The agent gets full autonomy. Your files stay where you left them. Everybody wins.
This guide walks through setup, daily use, verification, and troubleshooting. Written for macOS; Linux users, adjust accordingly.
What You Need
- Docker Desktop 4.58+ (the
docker sandboxsubcommand shipped in 4.58) - Claude Code CLI installed and working (
claude --version) - An Anthropic account (API key or OAuth, your choice)
Verify everything:
docker version # Need Docker Desktop 4.58 or later
docker ps # Confirm the daemon is running
claude --version # Confirm Claude Code is installed
If docker sandbox returns "not a docker command", update Docker Desktop.
How It Works (The Short Version)
When you run docker sandbox run claude ., Docker:
- Spins up a microVM (not a regular container; sandboxes do not appear in
docker ps) - Mounts your current working directory into the VM at the same absolute path
- Starts Claude Code with
--dangerously-skip-permissionsenabled by default - Stores your auth credentials in a Docker volume (
docker-claude-sandbox-data)
The microVM includes an Ubuntu-based environment with Node.js, Python 3, Go, Git, GitHub CLI, ripgrep, jq, and a private Docker daemon. The agent runs as a non-root agent user with sudo access.
One sandbox per workspace directory. If you run the command again in the same directory, Docker reuses the existing sandbox.
First-Time Setup
1. Create a throwaway project to test with
mkdir -p ~/claude-sandbox-test && cd ~/claude-sandbox-test
echo "# Test Project" > README.md
echo "print('Hello from the cage')" > test.py
git init && git add . && git commit -m "initial commit"
2. Launch the sandbox
docker sandbox run claude .
The first run pulls the template image and initializes the microVM, so it takes longer than subsequent runs.
3. Authenticate
Option A: API key (recommended for persistence)
Add to ~/.bashrc or ~/.zshrc:
export ANTHROPIC_API_KEY=sk-ant-api03-your-key-here
Then restart Docker Desktop. The sandbox daemon runs independently from your shell session, so it only picks up environment variables from your global shell config [^1].
Option B: Interactive OAuth
On first launch, Claude Code prompts you with a URL. Open it, complete the login, return to the terminal. Credentials persist in the Docker volume until the sandbox is removed.
4. Verify isolation
Inside the sandbox, try these:
> "List all files in /Users/yourusername/"
# Expected: only the mounted project directory is visible
> "Read ~/.ssh/id_rsa"
# Expected: file not found
> "Read ~/.aws/credentials"
# Expected: file not found
If Claude can see your SSH keys, something went wrong. Stop and investigate.
5. Exit
Press Ctrl+D or type /exit.
Daily Use
Interactive session
cd ~/your-project
docker sandbox run claude .
# work, talk, iterate
# Ctrl+D when done
One-shot prompt
docker sandbox run claude . -- -p "Add input validation to the signup handler"
Reconnect to an existing sandbox
docker sandbox run my-sandbox
Background (detached) mode
docker sandbox run -d claude .
docker sandbox ls # check status
docker attach <sandbox-name> # reconnect
Custom sandbox name
docker sandbox run --name api-work claude .
Sandbox Management
docker sandbox ls # list all sandboxes
docker sandbox stop <name> # stop one
docker sandbox stop $(docker sandbox ls -q) # stop all
docker sandbox rm <name> # remove one
docker sandbox rm $(docker sandbox ls -aq) # remove all
docker sandbox logs <name> # view logs
docker sandbox exec -it <name> bash # drop into a shell
Sandboxes are microVMs, not containers. They will not show up in docker ps. Use docker sandbox ls.
What Gets Isolated (and What Doesn't)
Isolated:
- Filesystem: the agent only sees your mounted workspace
- SSH keys, AWS credentials, browser data: not mounted
- Network: restricted (the sandbox has its own network stack)
- Docker: the sandbox has a private Docker daemon; containers it runs stay inside
Not isolated:
- Your project files: changes the agent makes in the workspace are reflected on your host machine immediately. This is the point. Commit before you let the agent loose.
Troubleshooting
"docker: 'sandbox' is not a docker command"
Your Docker Desktop is too old. You need 4.58 or later. Download from docker.com/products/docker-desktop.
Authentication required every time
Check the credentials volume:
docker volume ls | grep claude-sandbox-data
If missing, force a fresh auth:
docker sandbox run --credentials=none claude .
Complete the login. Credentials now persist until you destroy the sandbox or remove the volume.
Re-authenticate after session expiry
Inside an active session, type /login. Or destroy and recreate the sandbox.
Permission denied on project files
ls -la ~/your-project
sudo chown -R $(whoami) ~/your-project
Agent can't install system packages
By design. The sandbox ships with common dev tools. If you need a custom base image:
docker sandbox run --template your-custom-image:latest claude .
Multiple sandboxes eating RAM
Each sandbox uses roughly 1-2 GB of RAM. On a 16 GB machine, keep it to 2-3 simultaneous sandboxes. Monitor with docker sandbox ls and stop what you aren't using.
Git worktrees require separate auth
Known issue (docker/for-mac#7822). Each worktree path is treated as a distinct workspace, so you need to authenticate once per worktree. After that, credentials persist for each.
OAuth broken with Pro/Max plans ("proxy-managed" error)
Known issue (docker/for-mac#7842). If interactive OAuth fails, use the API key method instead.
Best Practices
- Commit before you hand over control. The agent writes directly to your project directory. If it makes a mess,
git checkout .gets you back. If you didn't commit, you get to reconstruct your changes from memory. - One sandbox, one project. Docker enforces this anyway (one sandbox per workspace path), but it bears repeating: don't mount broad directories.
- Stop sandboxes when idle. They consume RAM and CPU even when sitting there doing nothing.
- Test unfamiliar workflows in disposable directories first. Create a junk project, point the sandbox at it, see what happens.
- Do not mount your home directory. It defeats the entire purpose of sandboxing. The agent would have access to everything you're trying to protect.
Teardown
If you want to remove everything:
docker sandbox stop $(docker sandbox ls -q)
docker sandbox rm $(docker sandbox ls -aq)
docker volume rm docker-claude-sandbox-data
docker system prune -a # optional nuclear option for reclaiming disk space
References
- Docker Sandboxes for Claude Code - Official Docker documentation
- Getting Started with Docker Sandboxes - Prerequisites and setup
docker sandbox runCLI Reference - Full command reference- Docker Sandbox Workflows - Advanced usage patterns
- Docker Sandboxes: A New Approach for Coding Agent Safety - Design philosophy and architecture
[^1]: The Docker sandbox daemon runs outside your terminal session. Environment variables set with export in a running shell are invisible to it. Put them in your shell's rc file and restart Docker Desktop.
Tested on macOS with Docker Desktop 4.59 and Claude Code CLI (Feb 2026).