Development Container Setup
A new developer joins your team. They spend two days setting up their environment: installing Node.js, configuring PostgreSQL, fighting with Python version managers, and then discovering that Claude Code needs specific environment variables to work with your proxy. Dev containers eliminate this entirely — every developer gets an identical, pre-configured environment with Claude Code ready to go.
What You Will Walk Away With
Section titled “What You Will Walk Away With”- A production-ready devcontainer configuration with Claude Code pre-installed
- GitHub Codespaces setup for browser-based Claude Code access
- Patterns for sharing Claude Code configuration across containerized environments
- Security considerations for running Claude Code in containers
Basic Dev Container Setup
Section titled “Basic Dev Container Setup”The devcontainer.json File
Section titled “The devcontainer.json File”Create .devcontainer/devcontainer.json in your repository:
{ "name": "Project Dev Environment", "image": "mcr.microsoft.com/devcontainers/typescript-node:20", "features": { "ghcr.io/devcontainers/features/common-utils:2": {}, "ghcr.io/devcontainers/features/git:1": {} }, "postCreateCommand": "npm install && npm run build", "postStartCommand": "npm install -g @anthropic-ai/claude-code@latest", "forwardPorts": [3000, 5432], "customizations": { "vscode": { "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode" ] } }, "remoteEnv": { "NODE_ENV": "development" }}Custom Dockerfile
Section titled “Custom Dockerfile”For more control, use a Dockerfile:
# .devcontainer/DockerfileFROM mcr.microsoft.com/devcontainers/typescript-node:20
# Install Claude Code globallyRUN npm install -g @anthropic-ai/claude-code@latest
# Install project-specific toolsRUN apt-get update && apt-get install -y \ postgresql-client \ jq \ && rm -rf /var/lib/apt/lists/*
# Pre-configure Claude Code settings directoryRUN mkdir -p /home/node/.claudeReference it in devcontainer.json:
{ "build": { "dockerfile": "Dockerfile" }}GitHub Codespaces
Section titled “GitHub Codespaces”Codespaces provide cloud-hosted dev containers accessible from your browser or local VS Code.
Codespaces-Specific Configuration
Section titled “Codespaces-Specific Configuration”{ "name": "Codespace with Claude Code", "image": "mcr.microsoft.com/devcontainers/typescript-node:20", "postStartCommand": "npm install -g @anthropic-ai/claude-code@latest", "secrets": { "ANTHROPIC_API_KEY": { "description": "API key for Claude Code", "documentationUrl": "https://console.anthropic.com/settings/keys" } }, "portsAttributes": { "3000": { "label": "Application", "onAutoForward": "openBrowser" } }}The secrets field prompts developers to configure their API key when creating the Codespace.
Sharing Claude Code Configuration
Section titled “Sharing Claude Code Configuration”Mounting Local Config
Section titled “Mounting Local Config”Share your local Claude Code settings with the container:
{ "mounts": [ "source=${localEnv:HOME}/.claude,target=/home/node/.claude,type=bind,consistency=cached" ]}This shares your sessions, auto-memory, and personal settings with the container. Changes in the container are reflected on your host.
Project-Level Configuration
Section titled “Project-Level Configuration”Since .claude/settings.json, .claude/commands/, and .claude/agents/ are part of your repository, they are automatically available inside the container. No additional configuration needed.
Security Considerations
Section titled “Security Considerations”API Key Handling
Section titled “API Key Handling”Never hardcode API keys in devcontainer.json. Use one of these approaches:
- Environment variable passthrough:
"${localEnv:ANTHROPIC_API_KEY}" - Codespace secrets: Configured per-user in GitHub settings
- apiKeyHelper script: Generates keys dynamically from a secrets manager
Network Isolation
Section titled “Network Isolation”A custom Docker network plus a proxy env var is only a starting point — by itself it does not restrict egress, because nothing forces traffic through the proxy or blocks direct connections:
{ "runArgs": ["--network=project-network"], "remoteEnv": { "HTTPS_PROXY": "http://proxy:8080" }}To actually isolate the network, use a default-deny firewall that whitelists only the domains Claude Code needs (the Anthropic API, your package registry, your VCS host). The official Claude Code reference devcontainer does exactly this — see init-firewall.sh, which blocks all outbound traffic by default and verifies the rules on container startup.
Sandbox Mode
Section titled “Sandbox Mode”Claude Code ships a native sandbox that uses OS-level primitives to restrict filesystem and network access for the bash tool — but it is opt-in, off until you turn it on, not enabled by default. There is no CLAUDE_CODE_SANDBOX environment variable; enabling it through remoteEnv does nothing.
Turn the sandbox on from inside Claude Code by running the /sandbox command, which opens a menu of sandbox modes (and prints install instructions if dependencies like bubblewrap or socat are missing on Linux):
> /sandboxTo make it the default for everyone who opens the container, configure it under the sandbox key in .claude/settings.json (committed to the repo). Inside a container the sandbox adds defense in depth on top of container isolation — the two are complementary, not redundant. See the sandboxing docs for the full settings reference.
When This Breaks
Section titled “When This Breaks”Claude Code not found after container rebuild: The postStartCommand runs after every container start, but the postCreateCommand only runs on creation. Put Claude Code installation in postStartCommand to ensure it survives rebuilds.
Mounted .claude directory has wrong permissions: Container users may differ from your host user. Add a postStartCommand to fix permissions: "sudo chown -R node:node /home/node/.claude".
API key not available in container terminal: Make sure you are using ${localEnv:ANTHROPIC_API_KEY} (not ${containerEnv}). The localEnv prefix passes variables from your host machine.
Sessions from host do not appear in container: Sessions are stored by directory path. If the project path differs between host and container (e.g., /Users/you/project vs /workspaces/project), sessions will not match. This is expected behavior.
What is Next
Section titled “What is Next”- Enterprise Integration — Managed settings for container-based deployments
- GitHub Actions — CI/CD workflows that complement your dev container setup
- Proxy Configuration — Configure network access within containers