Claude Code runs inside Docker with full tool access. This guide covers the official image, custom Dockerfiles, docker-compose setups, volume mounting, and sandboxing for CI.
TL;DR
The fastest path: docker run -it -v $(pwd):/workspace -e ANTHROPIC_API_KEY ghcr.io/anthropics/claude-code:latest. Mounts your project, passes your key, drops you into the CLI. For production setups, build a custom image with your toolchain and use docker-compose for multi-service environments.
Official Docker Image
Anthropic publishes an official container image at ghcr.io/anthropics/claude-code. Tags follow CLI versions (e.g., :1.0.20) with :latest tracking the most recent stable release.
The image ships with:
- Node.js 20 LTS (Claude Code's runtime)
- The
claudeCLI, globally installed - ripgrep (
rg) for fast code search - git 2.43+ for worktree and version control operations
- A non-root user (
claude) as the default runtime user
The image does not include language-specific toolchains (Python, Go, Rust). If your project needs them, build a custom image. See the next section.
Quick Start
Run Claude Code in Docker
# Pull the latest image
docker pull ghcr.io/anthropics/claude-code:latest
# Run interactively with your project mounted
docker run -it \
-v "$(pwd)":/workspace \
-w /workspace \
-e ANTHROPIC_API_KEY=sk-ant-... \
ghcr.io/anthropics/claude-code:latest
# Run a one-shot command (non-interactive)
docker run --rm \
-v "$(pwd)":/workspace \
-w /workspace \
-e ANTHROPIC_API_KEY=sk-ant-... \
ghcr.io/anthropics/claude-code:latest \
claude --print "explain the main entry point"The -v flag mounts your current directory into /workspace inside the container. The -w flag sets the working directory. Claude sees your files, can edit them, and changes persist on your host filesystem.
API Key Security
Passing API keys via -e exposes them in docker inspect output. For production, use Docker secrets or a .env file with --env-file.
Custom Dockerfile
Most real projects need more than what ships in the base image. A custom Dockerfile lets you add your toolchain, pre-install dependencies, and configure the environment.
Custom Dockerfile for a Python project
FROM ghcr.io/anthropics/claude-code:latest
# Install Python and project tools
RUN apt-get update && apt-get install -y \
python3.12 python3.12-venv python3-pip \
&& rm -rf /var/lib/apt/lists/*
# Install project dependencies
COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt
# Copy CLAUDE.md so Claude understands the project
COPY CLAUDE.md /workspace/CLAUDE.md
WORKDIR /workspaceCustom Dockerfile for a Node.js + Go project
FROM ghcr.io/anthropics/claude-code:latest
# Install Go 1.22
RUN curl -fsSL https://go.dev/dl/go1.22.0.linux-amd64.tar.gz | tar -C /usr/local -xzf -
ENV PATH="/usr/local/go/bin:${PATH}"
# Install pnpm for the Node.js frontend
RUN npm install -g pnpm@9
WORKDIR /workspaceBuild with docker build -t my-project-claude . and run with the same volume mount pattern from the quick start. The image now has everything Claude needs to build, test, and lint your code.
Docker Compose for Teams
Docker Compose lets you define multi-service environments. Common pattern: Claude Code as the main service, with a database, cache, or test server running alongside it.
docker-compose.yml for Claude Code + PostgreSQL
services:
claude-code:
build: .
volumes:
- .:/workspace
working_dir: /workspace
env_file: .env
depends_on:
- db
stdin_open: true
tty: true
db:
image: postgres:16
environment:
POSTGRES_DB: myapp
POSTGRES_USER: dev
POSTGRES_PASSWORD: dev
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:Run docker compose run claude-code to start Claude with the database already running. Claude can run migrations, seed data, and execute tests against a real database, all in an isolated environment.
For teams, commit the docker-compose.yml and Dockerfile to your repo. Every developer gets the same Claude environment regardless of their host OS.
Volume Mounts and Persistence
Three directories matter when running Claude Code in Docker:
Essential volume mounts
docker run -it \
-v "$(pwd)":/workspace \ # Your project files
-v ~/.claude:/home/claude/.claude \ # Claude config, memory, API keys
-v ~/.ssh:/home/claude/.ssh:ro \ # SSH keys for git (read-only)
-w /workspace \
my-project-claude- /workspace: Your project. Changes here persist on the host. This is where Claude reads and writes code.
- ~/.claude: Claude's configuration directory. Contains
settings.json, memory files, and project-specific config. Mounting it preserves settings across container restarts. - ~/.ssh: For git operations over SSH. Mount read-only so Claude can pull and push but cannot modify your keys.
Git Credentials
If you use HTTPS for git, mount your git credential helper config or pass a GIT_TOKEN environment variable instead of SSH keys.
Sandboxing for CI Pipelines
Docker containers provide natural sandboxing for CI. Claude runs in an isolated environment where a bad command cannot damage the host system.
GitHub Actions example
name: Claude Code Review
on: pull_request
jobs:
review:
runs-on: ubuntu-latest
container:
image: ghcr.io/anthropics/claude-code:latest
steps:
- uses: actions/checkout@v4
- name: Run Claude review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude --print "review the changes in this PR for bugs and security issues"
claude --print "run the test suite and report failures"The container is ephemeral. It starts fresh on every run, cannot access other jobs' filesystems, and gets destroyed after the job completes. If Claude writes something unexpected, it disappears with the container.
Resource Limits
Claude Code is CPU-light (mostly waiting on API responses) but can spike during large file operations or ripgrep searches across big codebases.
Resource-limited container
docker run -it \
--cpus="2" \
--memory="4g" \
--pids-limit 100 \
-v "$(pwd)":/workspace \
-w /workspace \
-e ANTHROPIC_API_KEY \
ghcr.io/anthropics/claude-code:latest--cpus="2": Limits to 2 CPU cores. Enough for Claude CLI + ripgrep + git.--memory="4g": 4GB is comfortable. Increase for monorepos or heavy test suites.--pids-limit 100: Prevents fork bombs from runaway processes.
Docker vs Native vs Cloud Sandbox
| Docker Container | Native (Local) | Codex Cloud Sandbox | |
|---|---|---|---|
| Setup time | 30s (pull + run) | 2 min (npm install) | 0s (cloud-hosted) |
| Local tool access | Via mounts/custom image | Full | None |
| Filesystem isolation | Strong (container boundary) | None | Full (cloud VM) |
| Network isolation | Configurable | None | Disabled by default |
| Reproducibility | High (Dockerfile pinned) | Varies by machine | High (managed env) |
| CI/CD integration | Native | Requires setup | API-only |
Docker sits between the convenience of native and the isolation of cloud sandboxes. Use native for solo development when you trust the code. Use Docker for CI, teams, and projects where reproducibility matters. Use cloud sandboxes (like Codex) when you need full isolation and don't need local tools.
FAQ
Can I run Claude Code agent teams inside Docker?
Yes. Each agent runs in the same container by default. For stronger isolation, run each agent in its own container via docker-compose with shared volumes for the git repository. See worktree-based agent teams for the full architecture.
Does the Docker image support Apple Silicon?
Yes. The official image is multi-arch, publishing both amd64 and arm64 variants. Docker Desktop on Apple Silicon pulls the arm64 image automatically.
How do I update the Claude CLI inside the container?
Pull the latest image tag: docker pull ghcr.io/anthropics/claude-code:latest. If you use a custom Dockerfile, rebuild it. The base image update will include the new CLI version.
Can I use Morph as the API backend instead of Anthropic?
Yes. Set ANTHROPIC_BASE_URL=https://api.morphllm.com and ANTHROPIC_API_KEY to your Morph key. Claude Code routes through Morph for faster fast apply operations and lower token costs. Works identically in Docker.
Run Claude Code Through Morph
Morph routes Claude Code API calls through optimized infrastructure. 50% faster file edits with the fast apply model. Drop-in replacement: change one environment variable.