A secure, batteries-included dev container for developing with Claude Code. Run Claude Code with full permissions inside a sandboxed container while a network firewall ensures it can only reach the services it needs.
I've been using this setup daily for 6 months and it has been a game-changer for AI-assisted development.
| Component | Details |
|---|---|
| Runtime | Node.js 20 |
| Claude Code CLI | Pre-installed globally |
| Shell | Zsh with Powerlevel10k theme, fzf fuzzy finder |
| Git tooling | Git, GitHub CLI (gh), git-delta (beautiful diffs) |
| Network firewall | iptables rules that restrict outbound traffic (see Security Model) |
| Browser deps | Chromium libraries for Playwright MCP (optional) |
| Persistence | Shell history and Claude Code config survive container rebuilds via Docker volumes |
- Docker Desktop (Mac/Windows) or Docker Engine + Docker Compose (Linux)
- VS Code or Cursor with the Dev Containers extension installed
- Claude Code installed on your host machine (for running the setup prompt)
git clone https://github.com/YOUR_USERNAME/claude-code-devcontainer.git
cd claude-code-devcontainer- Open the cloned folder in VS Code or Cursor
- A notification will appear: "Folder contains a Dev Container configuration file. Reopen folder to develop in a container"
- Click "Reopen in Container"
- Wait for the container to build (first time takes a few minutes)
- Open the cloned folder in VS Code or Cursor
- Open the Command Palette:
Ctrl+Shift+P(Windows/Linux) orCmd+Shift+P(Mac) - Type and select: Dev Containers: Reopen in Container
- Wait for the build to complete
Once inside the container, open the terminal and run:
claudeBefore opening the dev container, use Claude Code to customize the configuration for your system. From the cloned repo folder:
claudeThen paste the prompt from SETUP_PROMPT.md.
Claude Code will read the .devcontainer/ files, ask you about your setup (project name, timezone, SSH keys, extra tools, firewall rules, etc.), and update the files for you. After that, open the folder in VS Code/Cursor and reopen in container — everything will be pre-configured.
The container runs a network firewall (init-firewall.sh) on startup that drops all outbound traffic by default and only allows connections to:
| Service | Why |
|---|---|
| GitHub (API, web, git) | Push/pull code, GitHub CLI |
| npm registry | Install packages |
| Anthropic API | Claude Code needs this |
| Statsig / Sentry | Claude Code telemetry |
| DNS (port 53) | Resolve domain names |
| SSH (port 22) | Git over SSH |
| localhost / host network | Access services on your host (e.g., databases) |
The firewall verifies itself after setup:
- Confirms
api.github.comis reachable - Confirms
example.comis blocked
This means Claude Code has full permissions to run any command inside the container, but cannot exfiltrate data to arbitrary servers. Your code stays safe.
These Docker capabilities are required for iptables/ipset to configure the firewall inside the container. Without them, the firewall script cannot run.
Allows the container to access services running on your host machine (databases, other dev servers) without complex port mapping. On Docker Desktop (Mac/Windows), note that --network=host behaves differently than on Linux — the container runs inside a VM, so "host" is the VM, not your Mac. Services on your Mac are accessible via host.docker.internal.
The container uses your host's TZ environment variable, falling back to UTC. To change:
# Set before opening the container
export TZ="Europe/London"Your host ~/.ssh directory is mounted into the container. If you need a specific SSH key for Git:
# Inside the container
export GIT_SSH_COMMAND="ssh -i /home/node/.ssh/your_key -F /dev/null"To let Claude Code control a browser, add this to the mcp.servers section in devcontainer.json under customizations > vscode > settings:
"mcp.servers": {
"playwright": {
"command": "npx",
"args": [
"-y",
"@playwright/mcp@latest",
"--cdp-endpoint",
"http://host.docker.internal:9223"
]
}
}You'll also need a Chromium instance running with --remote-debugging-port=9223 on your host.
To allow additional domains through the firewall, edit init-firewall.sh and add them to the domain list:
for domain in \
"registry.npmjs.org" \
"api.anthropic.com" \
"sentry.io" \
"statsig.anthropic.com" \
"statsig.com" \
"your-custom-domain.com"; do # <-- add hereThe firewall already allows connections to PostgreSQL (port 5432) on both localhost and your host network. For other databases, add similar iptables rules in init-firewall.sh.
.devcontainer/
devcontainer.json # Dev container configuration (VS Code / Cursor)
Dockerfile # Container image: Node.js 20 + tools + Claude Code
init-firewall.sh # Network firewall setup script
README.md # This file
SETUP_PROMPT.md # Copy-paste prompt for first-time Claude Code setup
Huge thanks to Cole Medin and his YouTube channel for the inspiration and framework behind this setup. His video on running Claude Code in dev containers was the starting point for this project, and I've been building on it for the past 6 months:
Cole Medin — Claude Code in Dev Containers
Cole's work in making AI coding tools accessible to everyone is incredible. If you're interested in AI-assisted development, definitely check out his channel.
MIT