claude-code-container
v1.0.4
Published
Run Claude Code in isolated Docker containers
Maintainers
Readme
Claude Code Container (ccc)
Single command. Isolated environment. No setup required.
Features
Run ccc in your project directory — no Dockerfile, docker-compose, port mapping, or volume config needed.
- Per-project isolated containers (path-hash based naming)
- Auto-forwarding of host env vars, locale (
LANG/LC_*), and timezone (TZ) - SSH keys and agent auto-mounted
- Auto-cleanup on session exit (stops container when last session ends)
- mise-based tool version management (auto-detect and create
mise.toml) - Built-in Chromium (headless testing support)
--network hostfor direct port access- macOS/Windows: transparent localhost proxy (iptables + fallback to
host.docker.internal) - Auto-pull Docker image from Docker Hub on first run (no manual
docker buildneeded) - Version-aware image management (auto-updates on
npm update)
Installation
npm (Recommended)
npm install -g claude-code-containerOn first ccc run, the Docker image (~2GB) is automatically pulled from Docker Hub. No manual build required.
For development setup, see CONTRIBUTING.md.
Quick Start
# Run Claude in current project (container auto-created)
ccc
# Continue previous session
ccc --continue
ccc --resume
# Open a shell in the container
ccc shell
# Run arbitrary commands
ccc npm install
ccc npm testHow It Works
~/.ccc/
├── claude/ # Claude credentials (mounted to /claude)
└── locks/ # Session lock files (per session)
Docker Volume:
└── ccc-mise-cache # mise cache (named volume, optimized for macOS/Windows)Session Lifecycle
- Start: Container created/started + session lock file created
- Running: Multiple sessions can run for the same project simultaneously
- Exit: Lock file deleted; container auto-stops if no other sessions remain
- Crash recovery: Stale lock files cleaned up on next run
Container names are fixed per project path hash, so claude --continue and --resume work correctly.
Image Management
ccc uses Docker image labels to manage versions:
| Scenario | Behavior |
|----------|----------|
| npm install (first run) | Auto-pulls matching version from Docker Hub |
| npm update | Detects version mismatch, auto-pulls new image |
| Local docker build -t ccc . | Uses local image, never auto-replaced |
| Offline with stale image | Warns but continues with existing image |
| Offline with no image | Error with instructions to build locally |
Override the registry with CCC_REGISTRY env var:
export CCC_REGISTRY=myregistry/claude-code-containerCommands
ccc # Run Claude
ccc shell # Open bash shell
ccc <command> # Run arbitrary command
ccc --env KEY=VALUE # Set additional env var
ccc stop # Stop current project's container
ccc rm # Remove current project's container
ccc status # Show CLI version, image info, and containers
ccc doctor # Health check and diagnostics
ccc clean # Clean stopped containers and imagesEnvironment Variables
Auto-Forwarding from Host
Host environment variables are automatically forwarded to the container.
export JIRA_API_KEY=xxx
ccc # JIRA_API_KEY is available inside the containerExcluded (to prevent system conflicts):
PATH,HOME,USER,SHELL,PWD- macOS-specific vars (
TERM_PROGRAM,ITERM_*,LC_TERMINAL, etc.)
Auto-forwarded: LANG, LC_ALL, LC_CTYPE (host locale), TZ (auto-detected)
Per-Session Environment Variables
ccc --env API_KEY=xxx --env DEBUG=trueContainer/Desktop Environment Separation
See the Tool Management (mise) section for details on separating container and desktop environments.
SSH Access
SSH configuration from the host is automatically used when Git SSH access is needed (private repo cloning, plugin installation, etc.).
Auto-Mounted (no setup required)
| Item | macOS (Docker Desktop) | Linux |
|------|----------------------|-------|
| SSH keys (~/.ssh) | Read-only mount | Read-only mount |
| SSH Agent | Docker Desktop built-in socket | $SSH_AUTH_SOCK auto-detected |
Troubleshooting SSH
# 1. Check if SSH keys are registered with the agent on host
ssh-add -l
# Add key if missing
ssh-add ~/.ssh/id_ed25519 # or id_rsa
# 2. Recreate container (to apply new mounts)
ccc rm
cccVerification
ccc shell
ssh-add -l # List agent keys
ssh -T [email protected] # Test GitHub connection
ssh -T [email protected] # Test GitLab connectionWorktree Workspaces (ccc @<branch>)
ccc @<branch> creates an isolated workspace per branch. It auto-creates git worktree entries for git repos in the current directory and runs Claude in the workspace.
Structure
~/projects/
├── my-project/ # Original (git repos + other files)
│ ├── backend/ # git repo
│ ├── frontend/ # git repo
│ └── shared/ # regular directory
└── my-project--feature/ # Workspace (auto-created)
├── backend/ # git worktree (feature branch)
├── frontend/ # git worktree (feature branch)
└── shared -> ../my-project/shared # symlinkGit repos are linked via git worktree; other items are symlinked.
Commands
# Create workspace + run Claude
ccc @feature
# Reuse existing workspace
ccc @feature --continue
# List workspaces + container status
ccc @
# Remove workspace (container + worktrees)
ccc @feature rm
# Force remove dirty worktrees
ccc @feature rm -fBranch Handling
- Local branch exists: Creates worktree from that branch
- Remote only: Creates local branch from
origin/<branch> - Doesn't exist: Creates new branch from HEAD
Branch / is converted to - in directory names (e.g., feature/login → my-project--feature-login/).
Parallel Work
Each workspace has its own container, so they can run simultaneously.
# Terminal 1
cd ~/projects/my-project && ccc @feature --continue
# Terminal 2 (simultaneously)
cd ~/projects/my-project && ccc @bugfix --continueTool Management (mise) — Zero-Config Project Setup
ccc uses mise to automatically manage per-project tool versions.
Auto-Detection
When running ccc for the first time in a project without mise.toml:
- Scans project files (
package.json,.nvmrc,pom.xml,build.gradle,go.mod, etc.) - Auto-detects tools and versions in use
- Prompts to create
mise.toml→ pressYto auto-generate
$ ccc
No mise.toml found in project.
Create mise.toml? (auto-detect tools) [Y/n]: Y
Scanning project files...
Found 3 version file(s), 2 version hint(s). Analyzing with Claude...
Created: /path/to/project/mise.tomlConfiguration Example
# .mise.toml
[tools]
node = "22"
java = "temurin-21"
[env]
_.file = [".env", "{% if env.container is defined %}.env.ccc{% else %}/dev/null{% endif %}"]mise install runs automatically on each ccc invocation, installing any required tools. The mise cache is stored in a Docker named volume (ccc-mise-cache), shared across projects and optimized for macOS/Windows performance.
Supported Tools
| Category | Tools |
|----------|-------|
| Per-project (mise.toml) | node, java, python, go, rust, ruby, php, deno, bun, terraform, kotlin, elixir, zig, dotnet |
| Global (built into image) | maven, gradle, yarn, pnpm |
Container/Desktop Environment Separation
The container=docker environment variable is automatically set inside the container. Use it in mise.toml to load different .env files per environment.
| File | Loaded in | Purpose |
|------|-----------|---------|
| .env | Always | Shared environment variables |
| .env.ccc | Container only | Container-specific overrides (e.g., DB_HOST=host.docker.internal) |
Container Image
Based on Ubuntu 24.04, includes:
- mise (tool version management)
- claude-code CLI
- Chromium (for headless testing,
CHROME_BINconfigured) - maven, gradle, yarn, pnpm
- Pre-generated locales (en_US, ko_KR, ja_JP, zh_CN, de_DE, fr_FR, es_ES, pt_BR)
- No memory/CPU/PID limits (shares host resources)
The image is available on Docker Hub:
docker pull luxusio/claude-code-container:latestContributing
See CONTRIBUTING.md for development setup, architecture, and release process.
License
MIT
