Running Claude Code in a Dev Container
Put Claude Code inside a dev container so every command it runs happens in an isolated, reproducible environment instead of on your machine. Adding the official Dev Container Feature, persisting login across rebuilds, enforcing policy with managed settings, restricting network egress, and the limits of the protection.
A dev container is a Docker container described by .devcontainer/devcontainer.json, which VS Code, Cursor, JetBrains IDEs and GitHub Codespaces can open as your development environment. (What is a dev container?)
Install Claude Code inside it and every command Claude runs — installs, tests, scripts — happens in the container, not on your machine. Your editor still edits the same project files. You get two things at once: a reproducible environment for the whole team, and an isolation boundary for the agent.
Adding Claude Code
Anthropic publishes a Dev Container Feature:
// .devcontainer/devcontainer.json
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
}
}
The :1.0 pins the feature's install script, not the Claude Code version — it installs the latest release, which then auto-updates. It installs Node.js if the image lacks it (if that fails, add ghcr.io/devcontainers/features/node:1 before it). In VS Code and Codespaces it also adds the Claude Code extension.
Rebuild (Dev Containers: Rebuild Container), open a terminal, run claude and sign in. If the browser login completes but never reaches the container, paste the code shown in the browser at the prompt.
Keep your login across rebuilds
The container's home directory is thrown away on rebuild. Persist Claude Code's config directory in a named volume:
"mounts": [
"source=claude-code-config-${devcontainerId},target=/home/node/.claude,type=volume"
],
"containerEnv": {
"CLAUDE_CONFIG_DIR": "/home/node/.claude"
}
Replace /home/node with your remoteUser's home. ${devcontainerId} gives each project its own volume. In Codespaces, store a token from claude setup-token (or an API key) as a Codespaces secret instead.
Enforce team policy
Claude Code reads /etc/claude-code/managed-settings.json on Linux at the highest precedence, so bake it into the image:
RUN mkdir -p /etc/claude-code
COPY managed-settings.json /etc/claude-code/managed-settings.json
Use it for permission deny rules, allowed MCP servers and similar. Remember anyone with write access to the repo can edit the Dockerfile — for policy engineers can't bypass, use server-managed settings or MDM. (Claude Code settings explained)
Environment variables for every session go in containerEnv — for example DISABLE_AUTOUPDATER=1 for reproducible builds (and install a pinned version with npm in the Dockerfile rather than using the feature).
Share project MCP servers through a committed .mcp.json, and install any binaries they need in the image. (Connecting MCP servers)
Restrict network egress
A container alone doesn't stop outbound traffic. Anthropic's reference dev container (in the claude-code repository) adds a firewall script that blocks everything except an allow-list — package registries, GitHub, the Anthropic API. Copy that approach if you'll let the agent run autonomously. (Egress control for AI agents)
Running without prompts
Inside a locked-down container with an egress firewall, running with fewer permission prompts — even --dangerously-skip-permissions — becomes far more reasonable, because the blast radius is the container. (Running Claude Code unattended)
The honest limits
Anthropic's own docs are explicit:
- With permissions skipped, a malicious repository can still exfiltrate anything inside the container — including the Claude credentials in
~/.claude. - Don't mount host secrets —
~/.ssh, cloud credential files. Prefer repository-scoped or short-lived tokens. - Use it with trusted repositories, and keep an eye on what Claude does.
Containers share the host kernel, so they're a strong convenience boundary, not the strongest isolation available. (Containers vs virtual machines, Firecracker vs gVisor vs containers)
Dev container vs the built-in sandbox
/sandbox |
Dev container | |
|---|---|---|
| Covers | Shell commands only | Everything Claude Code does |
| Setup | One command | A config file and Docker |
| Reproducible environment | No | Yes |
| Works on native Windows | No (use WSL2) | Yes, via Docker |
They combine well: sandbox inside the container for defence in depth. (Claude Code sandbox)
EasySpawn takes the next step up: each server is its own virtual machine with a dedicated kernel, where Claude Code works on your project with your app and database alongside — no Docker setup on your laptop required. See how it works or join the waitlist.
Related: What Is a Dev Container? · The Claude Code Sandbox · Run AI-Generated Code Safely · Containers vs Virtual Machines
Keep reading
The Claude Code Sandbox: Limit What Shell Commands Can Touch
Claude Code's built-in sandbox wraps the shell commands Claude runs in an OS-enforced boundary: writes limited to your project, network only to allowed domains. How to turn it on, auto-allow mode, allowWrite, denyRead, allowedDomains, excludedCommands, credential masking, and what runs outside it.
Claude Code --dangerously-skip-permissions: When It's Safe, and What to Use Instead
An agent that stops to ask permission can't work while you're away. An agent that never asks can delete things. How Claude Code's permission modes and allow/deny rules work, when skipping prompts is reasonable, and what has to be true of the environment first.