Agentic Coding

Devcontainer Comparison: Anthropic Reference vs. ai-capabilities

24 May 2026

claude devcontainer docker security

Compared 2026-05-24. Anthropic reference from claude-code/.devcontainer and docs.

Architecture

AspectAnthropic ReferenceThis Project
Base imagenode:20python:3.13-bookworm
CompositionSingle container, standalone DockerfileDocker Compose: sandbox + proxy sidecar
Network isolationiptables firewall inside the container (init-firewall.sh)Separate proxy container (tinyproxy) on internal Docker network
CapabilitiesRequires NET_ADMIN + NET_RAW (runArgs)No extra capabilities needed
ShellZsh with Powerlevel10k, fzf, persistent historyBash (no shell customization)
Usernode (built-in from base image)sandbox (created via useradd)

The firewall approach is the biggest architectural difference. Anthropic uses iptables+ipset inside the container, which requires CAP_NET_ADMIN/CAP_NET_RAW — elevated privileges that some security teams disallow. The proxy sidecar approach is arguably more principled: the sandbox container has zero direct internet access (Docker internal network), and traffic must flow through a separate container enforcing the allowlist. This is defense-in-depth — even if someone bypasses tinyproxy config, the Docker network topology prevents direct egress.

Dev Container Feature

Anthropic now recommends using their Dev Container Feature rather than a custom Dockerfile:

{
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "features": {
    "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
  }
}

This project installs Claude Code manually via npm install -g @anthropic-ai/claude-code in the Dockerfile. The Feature approach would simplify that step, but since the project needs Python 3.13 + uv + the proxy topology, the custom Dockerfile is the right call — the Feature is really for simpler setups.

Credential/Config Persistence

AspectAnthropic ReferenceThis Project
~/.claudeNamed Docker volume (claude-code-config-${devcontainerId})Fine-grained bind mounts from ~/.claude-sandbox/
AuthEntire ~/.claude in one volumeSingle .credentials.json bind mount
SettingsBundled in the volumeRead-only mounts from ~/.myai/dotclaude/
Per-project isolation${devcontainerId} in volume nameDirectory structure under ~/.claude-sandbox/ai-capabilities/

The bind-mount strategy is more granular and more secure. Anthropic mounts the entire ~/.claude as one volume. This project mounts individual files read-only (settings, commands, skills, hooks) and only makes credentials and per-project data writable. This means the sandbox can’t accidentally modify the host’s Claude configuration. The tradeoff is more lines in docker-compose.yml to maintain.

Domain Allowlist Coverage

DomainAnthropicThis Project
Anthropic/ClaudeYesYes
SentryYesYes
GitHubYes (IPs via API)Yes (regex)
npmYesYes
VS Code marketplaceYesYes
StatsigYesNo
Linear MCPNoYes
PyPINoYes
OpenAI / GoogleNoYes
Go / Rust registriesNoYes

Anthropic’s firewall allowlists at the IP level (resolves DNS, adds IPs to ipset), so it catches CDN IP changes poorly. The regex-based hostname matching via tinyproxy is more robust for domains behind CDNs.

The project allowlist is broader because it calls multiple AI vendor APIs, while Anthropic’s reference only needs Claude.

Missing from the project allowlist: statsig.com and statsig.anthropic.com — used by Claude Code for feature flags. If Claude Code ever behaves oddly (features not enabling), this could be why. Though DISABLE_AUTOUPDATER=1 is set, reducing the impact.

Things Anthropic Does That This Project Doesn’t

  1. NODE_OPTIONS=--max-old-space-size=4096 — avoids OOM in long Claude Code sessions. Worth adding if crashes have been observed.
  2. CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 — mentioned in docs for org policy. Not set here but could be, since the proxy already blocks non-essential domains.
  3. Managed settings via /etc/claude-code/managed-settings.json — recommended path for enforcing org policy. Not relevant for a personal project.
  4. git-delta — nice diff viewer. Low-priority nicety.
  5. Persistent shell history — Anthropic mounts a volume for bash history. This sandbox loses history on restart.

Things This Project Does That Anthropic Doesn’t

  1. Proxy sidecar — cleaner network isolation without elevated capabilities.
  2. Entrypoint script — auto-runs uv sync, fixes git remotes, configures MCP, prints integration status. Anthropic’s container has none of this automation.
  3. Dual-mode launch — devcontainer mode vs. CLI mode in the entrypoint. Anthropic’s reference only targets VSCode devcontainers.
  4. CLAUDE.md / skills / hooks — read-only mounts of personal config. Anthropic’s reference is a blank slate.
  5. Multi-vendor API keys.env file with Anthropic/OpenAI/Gemini keys. Anthropic’s reference only handles Anthropic auth.

Recommendations

  1. Add NODE_OPTIONS=--max-old-space-size=4096 to docker-compose environment — prevents Node.js OOM in long sessions.
  2. Add statsig.anthropic.com and statsig.com to the proxy allowlist for Claude Code feature flags.
  3. No need to switch to the Dev Container Feature — the custom Dockerfile gives Python/uv/proxy integration that the Feature can’t provide.
  4. The proxy approach is better than Anthropic’s iptables approach for a Docker Compose setup — no elevated capabilities needed, and the separation of concerns is cleaner. Keep it.
  5. Shell history persistence is a low-effort quality-of-life add for interactive sandbox-shell use. Add a volume mount for /home/sandbox/.bash_history.