Claude Code in Docker and dev containers

A container is the only environment where letting an agent act without asking is a considered decision rather than a shrug. It is also the one place where a rebuild can silently sign you out every morning if you set it up carelessly.

By the Continuum team. We build a workbench that runs Claude Code, Codex, and their peers, so the model rates quoted here are the ones our own cost analytics ship with.

The short version

For a team environment, add the Claude Code Dev Container Feature to .devcontainer/devcontainer.json and rebuild; that is the whole install. For CI, build a plain image with a pinned version and DISABLE_AUTOUPDATER=1. In both cases run as a non-root user, pass credentials at runtime rather than baking them into a layer, and mount a named volume at ~/.claude with CLAUDE_CONFIG_DIR pointing at it so sign-in survives a rebuild. Inside a container with restricted egress, skipping permission prompts is defensible. Accurate as of August 2026.

What you need to know
  • One feature line installs it: ghcr.io/anthropics/devcontainer-features/claude-code:1.0.
  • Mount a volume at ~/.claude and set CLAUDE_CONFIG_DIR, or you re-authenticate every rebuild.
  • Run as a non-root user. The CLI refuses --dangerously-skip-permissions as root.
  • Never bake credentials into an image. Runtime environment or a mounted secret.
  • Fully offline does not work: the API is a hard dependency. Use an egress allowlist.
  • Do not mount ~/.ssh or cloud credential files into an agent container.

The one-line dev container install

If your team already uses dev containers, this is the entire installation. The feature works with anything that supports the Dev Containers specification, including VS Code, GitHub Codespaces, JetBrains IDEs and Cursor.

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

Rebuild

In VS Code, open the Command Palette with <kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> or <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd> and run Dev Containers: Rebuild Container. In Codespaces or the Dev Containers CLI, use the equivalent rebuild action.

02

Sign in inside the container

claude

If the browser sign-in completes but the callback never reaches the container, copy the code shown in the browser and paste it at the Paste code here if prompted prompt. That is a port-forwarding artefact, not a failure.

A plain image, for CI

A pipeline does not want a feature that always installs the newest release. Build the version you tested.

Minimal, pinned, non-root.
FROM node:22-bookworm-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
      git curl ca-certificates ripgrep less \
    && rm -rf /var/lib/apt/lists/*

ARG CLAUDE_VERSION=2.1.89
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_VERSION}
ENV DISABLE_AUTOUPDATER=1

# An agent that can write to system paths is a worse agent, not a better one.
RUN useradd -m -s /bin/bash agent
USER agent
WORKDIR /workspace

ENTRYPOINT ["claude"]
Running it. Credentials arrive at runtime, never in a layer.
docker build -t claude-agent .

docker run --rm -it \
  -v "$PWD:/workspace" \
  -e ANTHROPIC_API_KEY \
  claude-agent

Credentials that survive a rebuild

By default the container home directory is discarded on rebuild, so every engineer signs in again every time. The fix has two halves and skipping either one leaves you signed out.

devcontainer.json, for a container whose remoteUser is node.
"mounts": [
  "source=claude-code-config-${devcontainerId},target=/home/node/.claude,type=volume"
],
"containerEnv": {
  "CLAUDE_CONFIG_DIR": "/home/node/.claude"
}
  • Codespaces keeps ~/.claude across stop and start, but clears it on rebuild, so the same configuration applies.
  • To carry authentication across codespaces, store ANTHROPIC_API_KEY, or a CLAUDE_CODE_OAUTH_TOKEN from claude setup-token, as a Codespaces secret. Secrets appear as environment variables inside the container automatically.
  • Cloud providers pass credentials through containerEnv, a Codespaces secret, or workload identity. Do not mount credential files from the host.

Restricting what the container can reach

If the agent will run code you have not read, which is the normal case the moment it installs a dependency, limit where the container can go. Start from the list of hosts Claude Code genuinely needs.

The core allowlist. Verified against the network reference, August 2026.

HostNeeded for
api.anthropic.comModel requests, feature flags, telemetry events
claude.ai and claude.comAccount sign-in
platform.claude.comConsole sign-in, and OAuth token exchange and refresh
downloads.claude.aiNative installer, auto-updater, plugin downloads
registry.npmjs.orgOnly if you install or update through npm
mcp-proxy.anthropic.comOnly if you use claude.ai connectors

The reference dev container ships an init-firewall.sh that blocks everything outbound except the domains Claude Code and your toolchain need. Running a firewall inside a container needs extra privileges, so the reference grants NET_ADMIN and NET_RAW through runArgs. Neither the script nor those capabilities is required by Claude Code itself; if you already control egress at your own network boundary, leave them out.

The permission argument

On a laptop, approval prompts are the only thing between an agent and your filesystem, your SSH keys and your shell history. In a container with only the repository mounted and egress restricted, the blast radius is the repository and you can throw the container away.

Reasonable here. Not reasonable on your laptop.
docker run --rm -it \
  -v "$PWD:/workspace" \
  -e ANTHROPIC_API_KEY \
  claude-agent --dangerously-skip-permissions

What the container boundary is actually buying you.

RiskOn the hostIn a container
Destructive command outside the repoRealContained
Reading SSH keys or shell historyPossibleNot mounted, if you did not mount them
Installing packages globallyAffects your machineThrown away
Network egressUnrestrictedRestrictable
Exfiltrating the Claude credential in ~/.claudeRealReal
Damage to the repository itselfReal either wayReal either way
  • The CLI refuses the flag as root. Confirm remoteUser is a non-root account, or the flag simply will not run.
  • Want fewer prompts without turning them off? Auto mode has a classifier review actions before they run, which is the middle setting most teams actually want.
  • To forbid the flag entirely, set permissions.disableBypassPermissionsMode to "disable" in managed settings.
The container boundary keeps the agent away from your SSH keys and the rest of the disk, but the repository and the credential you mounted through it are inside the blast radius your machine ~/.ssh shell history other repos not mounted, not reachable the container agent prompts skipped inside the blast radius /workspace the repo you mounted ~/.claude the credential you mounted installed packages thrown away on exit egress allowlist: api.anthropic.com, npm registry It protects your machine, not the repo or the credential you mounted in.

Policy that travels with the image

A container is a convenient place to apply policy, because the same image runs on every machine. On Linux, Claude Code reads /etc/claude-code/managed-settings.json at the highest precedence in the settings hierarchy.

Copy policy in from the Dockerfile.
RUN mkdir -p /etc/claude-code
COPY managed-settings.json /etc/claude-code/managed-settings.json
Environment for every session in the container.
"containerEnv": {
  "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
  "DISABLE_AUTOUPDATER": "1"
}

Questions people ask

Install it into an image with npm at a pinned version, set DISABLE_AUTOUPDATER=1, run as a non-root user, mount your repository at the working directory, and pass credentials as runtime environment variables rather than baking them into a layer.

Add ghcr.io/anthropics/devcontainer-features/claude-code:1.0 to the features block of .devcontainer/devcontainer.json and rebuild the container. The feature also installs the VS Code extension when you open the container in VS Code or Codespaces.

Because the container home directory is discarded. Mount a named volume at ~/.claude and set CLAUDE_CONFIG_DIR to the same path, so the separate ~/.claude.json file that holds your account also lands inside the volume.

More defensible than anywhere else, because the boundary limits the damage to what you mounted. It still does not protect the repository or the Claude credential inside the container, so use it with trusted repositories, restrict egress, and commit before an unattended run.

Use remoteEnv with ${localEnv:ANTHROPIC_API_KEY} in devcontainer.json, which reads the variable from your machine at start, or store it as a Codespaces secret. Either way it never enters the image or the repository.

No. Model requests to api.anthropic.com are a hard dependency. An egress proxy that allows the Anthropic hosts plus your package registry, and denies everything else, is the workable version of this.

No. The repository is mounted read-write, which is the point. The container protects your machine and everything you chose not to mount, which is why mounting ~/.ssh into an agent container defeats the exercise.

Yes, and disable the auto-updater in the same step. The Dev Container Feature always installs the newest release, so a build that must be reproducible installs the CLI from the Dockerfile at an explicit version instead.

Sources

Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.

  1. Claude Code development containers
  2. Claude Code network configuration
  3. Claude Code setup and install
  4. Claude Code settings reference
Try it

Sandboxed,
and visible.

Continuum runs sessions in isolated worktrees with per-session diff review, so you always see what an unattended agent actually changed.

free app · your subscriptions · local-first