Kipt

Your prompts and skills, one keystroke away.

Explore

Claude Code in Docker: build an image, sign in, and run it safely

Claude Code Docker guide: install it in an image, pass credentials, persist login, run claude -p unattended as non-root, and limit network egress.

By the Kipt team · Updated 26 October 2026

To run Claude Code in Docker, install it in an image with the native installer or npm install -g @anthropic-ai/claude-code, mount your project into the container, pass a credential such as ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN, and run claude as a non-root user. If you work in VS Code, Codespaces or a JetBrains IDE, the official Dev Container Feature does most of this for you.

The main reason to use a container is isolation: commands Claude runs execute inside it, not on your machine, which makes unattended runs much safer. This guide follows Anthropic's sandbox environments and development containers pages, read on 26 October 2026.

Why run Claude Code in a container?

Claude Code's own sandbox only wraps shell commands. Built-in file tools, MCP servers and hooks still run on your host. A container puts the whole Claude Code process inside one boundary.

Anthropic compares the options like this:

Approach What is isolated Needs Docker Setup effort
Sandboxed Bash tool (/sandbox) Shell commands and their child processes No Minimal on macOS, low on Linux and WSL2
Sandbox runtime (srt claude) The whole Claude Code process No Low
Dev container Full development environment Yes Medium
Custom container Full development environment Yes Medium to high
Virtual machine Full operating system No High
Cloud sessions Full OS, hosted by Anthropic No None; needs a Claude subscription

The docs are direct about unattended work: "Always run --dangerously-skip-permissions sessions inside a container, a VM, or the sandbox runtime." For an untrusted repository, they recommend a dedicated VM or a cloud session over a container.

How do you build a Docker image with Claude Code?

Claude Code runs on Ubuntu 20.04+, Debian 10+ and Alpine Linux 3.19+, with 4 GB of RAM or more, according to the setup page. The docs list npm, the native installer, and apt, dnf or apk packages; the two below are the simplest in a Dockerfile.

npm. The package needs Node.js 22 or later. The Dockerfile below is our own example, not an official Anthropic image; it uses only the documented npm install -g @anthropic-ai/claude-code command:

# Example only: not an official Anthropic image
FROM node:22-bookworm-slim

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

# install as the non-root "node" user that ships with this image
USER node
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global
ENV PATH=$PATH:/home/node/.npm-global/bin

# pin a release with: docker build --build-arg CLAUDE_CODE_VERSION=X.Y.Z .
ARG CLAUDE_CODE_VERSION=latest
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}

# create the config folder as "node" so a named volume mounted here is writable
RUN mkdir -p /home/node/.claude

# the image controls the version, so stop self-updates
ENV DISABLE_AUTOUPDATER=1
WORKDIR /workspace

The devcontainer docs recommend installing a pinned @anthropic-ai/claude-code@X.Y.Z and setting DISABLE_AUTOUPDATER for reproducible builds, so pass a release number with --build-arg instead of relying on latest. The docs also warn against sudo npm install -g, which is why the example installs into a user-owned prefix. Creating /home/node/.claude as the node user lets the non-root user write to a named volume mounted there later.

Native installer. Run curl -fsSL https://claude.ai/install.sh | bash as the user who will run Claude Code. It places the launcher at ~/.local/bin/claude. Add a version to pin it: bash -s 2.1.89 in the docs' example.

On Alpine, the docs say to install bash, curl, libgcc, libstdc++ and ripgrep first, then set USE_BUILTIN_RIPGREP to 0 in your settings env.

How do you run it and sign in?

Mount your project and pass a credential from your shell, never baked into the image:

docker build -t claude-code .

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

-e ANTHROPIC_API_KEY with no value copies the variable from your shell. Pick the credential that matches how you pay:

You have Pass this Notes
A Claude Console account ANTHROPIC_API_KEY Billed per token
A Pro, Max, Team or Enterprise plan CLAUDE_CODE_OAUTH_TOKEN Create it with claude setup-token on a machine with a browser; it lasts one year
Bedrock, Agent Platform or Foundry CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX or CLAUDE_CODE_USE_FOUNDRY plus your cloud credentials No browser prompt
Nothing scripted Run claude and sign in If the browser callback never reaches the container, paste the code at Paste code here if prompted

According to the authentication docs, claude setup-token "does not save the token anywhere", so copy it into your secret store straight away. Our environment variables guide explains which credential wins when several are set.

How do you keep your login and settings between runs?

Claude Code keeps credentials, settings and history in ~/.claude, and account details and per-project trust in ~/.claude.json. On Linux, credentials live in ~/.claude/.credentials.json. A fresh container loses all of it.

The fix from the devcontainer docs works in plain Docker too: mount a named volume at ~/.claude and point CLAUDE_CONFIG_DIR at it, so .claude.json lands in the volume as well.

docker run -it --rm \
  -v "$PWD":/workspace \
  -v claude-config:/home/node/.claude \
  -e CLAUDE_CONFIG_DIR=/home/node/.claude \
  claude-code claude

Without CLAUDE_CONFIG_DIR, Claude Code repeats first-run setup each time because .claude.json stays outside the volume.

How do you run Claude Code unattended in Docker?

Combine headless mode with bypass permissions, as a non-root user:

docker run --rm \
  -v "$PWD":/workspace \
  -e CLAUDE_CODE_OAUTH_TOKEN \
  claude-code \
  claude -p "run the tests and fix any failures" --dangerously-skip-permissions

If the container runs as root, Claude Code stops with: --dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons. That is why the image above switches to the node user.

Keep in mind what the container does not stop. The docs warn that with this flag, a malicious project can exfiltrate anything inside the container, "including the Claude Code credentials stored in ~/.claude." Claude can also change every file in the mounted folder, and those changes land on your host. Use trusted repositories, avoid mounting ~/.ssh or cloud credential files, and prefer short-lived tokens.

For a middle ground, auto mode has a classifier review each action instead of skipping checks. See our headless guide for output formats and --max-turns, and our permissions guide for allow and deny rules.

How do you limit network access from the container?

Network egress is what turns a contained mistake into a data leak, so allow only what Claude Code needs. The network configuration page lists the hosts, including:

Host Needed for
api.anthropic.com Claude API requests
claude.ai claude.ai account sign-in
platform.claude.com Console sign-in, and OAuth token refresh for claude.ai accounts
downloads.claude.ai Native installer and auto-updates
registry.npmjs.org npm installs and npx-launched MCP servers

Anthropic's reference dev container ships an init-firewall.sh script with a default-deny allowlist. Running a firewall inside a container needs the NET_ADMIN and NET_RAW capabilities, but the docs note you can skip the script and rely on your own network controls instead.

Behind a corporate proxy, set HTTPS_PROXY and, for a custom CA, NODE_EXTRA_CA_CERTS.

Can you use /sandbox inside a container?

Yes. Layering the Bash sandbox inside a container adds per-command limits on top of the container boundary. In an unprivileged container, though, bubblewrap can't mount a fresh /proc and fails with an error like Can't mount proc on /newroot/proc: Operation not permitted. The sandboxing docs say to set sandbox.enableWeakerNestedSandbox to true in that case, and only when the outer container already gives you the isolation you need.

Should you use a devcontainer instead?

If your team opens projects in VS Code, GitHub Codespaces or a JetBrains IDE, probably yes. Add one line to .devcontainer/devcontainer.json:

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

The :1.0 tag pins the install script, not Claude Code, which installs at the latest version. Organizations can copy a managed-settings.json to /etc/claude-code/ in the Dockerfile for policy, though anyone with write access to the repo can change that step. Our devcontainer guide covers persistence, policy and the reference firewall in detail.

For the strongest separation, the docs point to a virtual machine, Docker Sandboxes (a microVM product from Docker) or Anthropic-hosted cloud sessions.

How do you bring your skills into the container?

A clean container starts without your personal skills. If you keep them in a GitHub repo, one command in your image or startup script can install them. Kipt, for example, stores prompts and Agent Skills as Markdown in a private repo you own and installs every skill into Claude Code with npx skills add https://github.com/<you>/<repo>.git --all -g. In practice, that step needs network access to GitHub and the npm registry, and because the repo is private, git inside the container also needs credentials that can read it. Pass a read-only token at run time rather than baking it into the image.

Questions

Is there an official Claude Code Docker image?

Anthropic's docs do not point to a maintained base image. They offer the Claude Code Dev Container Feature and a reference dev container in the anthropics/claude-code repository, which Anthropic calls a working example rather than a maintained base image. For plain Docker, install Claude Code in your own image.

How do I log in to Claude Code inside a Docker container?

Pass a credential as an environment variable: ANTHROPIC_API_KEY for a Claude Console key, or CLAUDE_CODE_OAUTH_TOKEN from claude setup-token for a Claude subscription. You can also run claude interactively and sign in through the browser; if the callback doesn't reach the container, paste the code at the prompt.

Why does --dangerously-skip-permissions fail in my container?

On Linux and macOS, Claude Code refuses bypassPermissions mode when it runs as root or under sudo, with the message that the flag cannot be used with root/sudo privileges. Add a non-root user to your image and run claude as that user.

How do I keep my Claude Code login when the container is recreated?

Mount a named volume at the user's ~/.claude directory and set CLAUDE_CONFIG_DIR to the same path. Claude Code then writes both its credentials and the .claude.json file into the volume, so they survive rebuilds.

Can I use the /sandbox feature inside Docker?

Yes, on a Linux container, but bubblewrap can fail in an unprivileged container with an error about mounting proc. Set sandbox.enableWeakerNestedSandbox to true in that case, and only when the container itself is the isolation boundary you rely on.

Does running Claude Code in Docker make it fully safe?

No. The docs say isolation reduces the impact of a breach but does not remove risk. Claude can still change any files you mount, and with network access it can leak anything it can read, including its own credentials. Limit egress and use trusted repositories.

More in Claude Code

All guides

Keep your prompts and skills in one place, in your own GitHub. Install every skill with one command.

Get started

Kipt is an independent product, not affiliated with or endorsed by Anthropic, OpenAI, Cursor or GitHub. Claude, ChatGPT, Codex, Cursor and GitHub are trademarks of their owners.