The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Claudebox listing page.
A runtime harness for Claude Code — the agentic coding CLI from Anthropic — running in a fully isolated Docker container with every dev tool pre-installed, passwordless sudo, docker-in-docker support, and --permission-mode bypassPermissions enabled by default.
v2.0.0 — rebased on
psyb0t/aicodebox. claudebox is now a thin child image of the shared aicodebox base (same pattern aspsyb0t/pibox). Every mode surface (API / Telegram / Cron / MCP) is inherited from the base and stays in lockstep with future base fixes. SeeCHANGELOG.mdfor the full migration guide (endpoint shape changes, env-var namespace, path renames — all mitigated by aliases + symlinks so existing configs keep working).
Runtime hardening (recommended docker run flags):
--cap-drop=ALL --cap-add=NET_BIND_SERVICE — drop every Linux capability, add back only bind-below-1024 if you actually need it.--security-opt no-new-privileges:true — block setuid privilege escalation inside the container.--memory=2g --cpus=2 --pids-limit=512 — cap runtime resource use so a runaway process can't starve the host.--read-only --tmpfs /tmp:rw,noexec,nosuid (only if you don't use /workspace for writes — otherwise skip).
The container drops from root to aicode (UID 1000) at boot via setpriv in the base entrypoint, so the process running your code is never root even without --user.claudebox wraps Claude Code with several distinct interfaces:
claude command, with persistent containers and automatic session resumption across runschat/completions adapter that lets LiteLLM, OpenAI SDKs, and any OpenAI-compatible client talk to Claude Code, complete with streaming SSE, multi-turn conversations, and multimodal image handlingBeyond just running Claude Code in Docker, claudebox adds skill injection (auto-load SKILL.md files into every session), init hooks, custom script directories, structured JSON logging, and a workspace management layer that handles multi-tenant isolation with automatic busy/idle tracking.
Renamed from
docker-claude-code: This project was previously calleddocker-claude-codewith the Docker image atpsyb0t/claude-code. Starting with v1.0.0, it isclaudebox— the Docker image is nowpsyb0t/claudebox, the default binary name isclaudebox, the GitHub repository ispsyb0t/docker-claudebox, and the SSH key directory defaults to~/.ssh/claudebox. If you were using the old names, update your image references, wrapper scripts, and SSH paths accordingly.
Docker installed and running. That's it.
The install script pulls the Docker image, generates SSH keys for git operations inside the container, downloads the wrapper script, and installs it as a command on your system.
v2 note: the variant naming flipped in v2.
latestis now the minimal image (was the full image pre-v2);latest-fullis the toolchain-loaded variant (waslatestpre-v2). TheCLAUDEBOX_MINIMAL=1opt-in from v1 is now a no-op — you already get minimal by default. SetCLAUDEBOX_FULL=1to opt into the toolchain image. Installing withCLAUDEBOX_FULL=1(as above) bakes the choice into the installed wrapper, so the full variant sticks for every run — you don't need to keep the env var set afterward.
Heads up on env vars:
VAR=x curl … | bashdoes not setVARfor the install script — bash semantics attach the var tocurlonly. Alwaysexportthe var first (or put it on thebashside of the pipe).
If you prefer not to pipe scripts to bash:
psyb0t/claudebox:latest (minimal, default)The default v2 image. Just enough to run Claude Code on top of the aicodebox base: Ubuntu 24.04, git/curl/wget/jq, Node.js 24 LTS + npm, Python 3.14 + uv, Docker CE. Claude has passwordless sudo, so it will install whatever else it needs on the fly via apt-get, pip, npm, etc. Smaller image, faster pull, first run may take longer while Claude sorts out its own tooling.
Claude Code is installed on first run, not baked into the image. Anthropic's Claude Code CLI is proprietary and can't be redistributed, so the image ships only the pinned version (
CLAUDEBOX_CLAUDE_VERSION, default set at build) and the entrypoint runsnpm install -g @anthropic-ai/claude-code@<version>from npm the first time a fresh container starts. This means the published image redistributes none of Anthropic's software, and each container pulls Claude Code straight from npm. First container start needs network and takes a few extra seconds; warm restarts skip it. To pin a different version, setCLAUDEBOX_CLAUDE_VERSIONatdocker run.
Use /aicodebox-init.d/*.sh hooks (see Init Hooks) to pre-install your tools on first container create so Claude doesn't burn tokens figuring out package management.
psyb0t/claudebox:latest-full (toolchain-loaded)Everything pre-installed. Layered on top of the minimal image: Go 1.26.7, Python 3.14.7 via pyenv, Node.js dev tools, C/C++ toolchain, terraform, kubectl, helm, gh, database clients (sqlite/postgres/mysql/redis), editors (vim/nano/htop/tmux), linters + formatters (flake8/black/isort/pyright/mypy/ruff/eslint/prettier/gofumpt/…). Larger image but Claude wakes up ready.
latest (minimal) | latest-full | |
|---|---|---|
| Ubuntu 24.04 | yes | yes |
| git, curl, wget, jq | yes | yes |
| Node.js LTS + npm | yes | yes |
| Docker CE + Compose | yes | yes |
| Claude Code CLI | yes | yes |
| Go 1.26.7 + tools | yes | - |
| Python 3.14.7 + tools | yes | - |
| Node.js dev tools | yes | - |
| C/C++ tools | yes | - |
| DevOps (terraform, kubectl, helm, gh) | yes | - |
| Database clients | yes | - |
| Shell utilities (ripgrep, bat, etc.) | yes | - |
Languages and runtimes:
DevOps and infrastructure:
gh)Database clients:
psql), mysql-client, redis-tools (redis-cli)Shell and system utilities:
Container automation:
CLAUDE.md in each workspace listing all available tools, so Claude knows what it has access to--update)~/.claude/bin (added to PATH automatically)~/.claude/init.d/*.sh (run once on first container create)~/.claude/.always-skills/ (injected into every invocation)--continue / --no-continue / --resume <session_id>DEBUG=trueYou need either an Anthropic API key or an OAuth token. Set up once, use everywhere:
claudebox can run in several modes — pick the one that matches how you want to use Claude Code. Each has its own page with full setup, env vars, and examples.
Drop-in replacement for claude. Persistent per-workspace container, automatic session resumption, plus utility commands like claudebox doctor, claudebox mcp list, claudebox stop, and claudebox clear-session.
Non-interactive prompt → response for scripts, pipelines, and automation. Plain text, JSON, and native stream-json output formats. Model selection, system prompt overrides, JSON-schema-constrained output, and session continuation. For a stable full-event response, use API mode with eventMode: "full".
Run as a long-lived HTTP server. Full REST API for prompts and file ops with workspace isolation, async runs with run-id polling, OpenAI-compatible chat/completions endpoint (streaming + multimodal + LiteLLM compatible), and an MCP endpoint over streamable HTTP so other agents can use Claude Code as a tool.
Talk to Claude from Telegram. Per-chat isolated workspaces, configurable models/effort/system-prompts per chat, allowed-chats and per-chat allowed-users gating, file/photo/video/voice ingestion, /fetch, /cancel, /status, /config, /reload commands, and [SEND_FILE: path] for Claude to send files back.
YAML-defined scheduled jobs. Standard 5-field cron or 6-field for sub-minute resolution. Per-job stream-json history under ~/.claude/cron/history/<workspace-slug>/<ts>-<job>/, foreground process so docker logs shows every tick, overlap protection. Set model at the root of the YAML as a default for all jobs; override per-job as needed.
Expose Claude Code as an MCP server over streamable HTTP, so other agents can drive it as a tool — run_prompt plus workspace-confined file tools. Not a foreground mode: it runs as a sidecar alongside telegram, cron or interactive on its own port, and is already mounted at /mcp on the API port when the foreground is API mode.
CLAUDEBOX_* settings the wrapper and entrypoint understand, plus CLAUDEBOX_ENV_* (forward arbitrary vars into the container) and CLAUDEBOX_MOUNT_* (extra volume mounts).~/.claude/bin), one-time init hooks (~/.claude/init.d), always-active skills auto-injected into every session (~/.claude/.always-skills), and MCP server definitions (project .mcp.json or global ~/.claude.json).The skill works in any agent that reads .agents/skills/, and installs natively in the clients below.
Claude Code prompts for the claudebox server URL and, if the MCP surface has auth enabled, the bearer token — the token is stored in your OS keychain.
Installed via the marketplace, the skill invokes as $claudebox:claudebox. Codex also picks the skill up automatically, with no install, in any repo containing .agents/skills/ — there it invokes as plain $claudebox.
The skill is published to ClawHub on every release:
For MCP clients that speak local stdio, the @psyb0t/claudebox plugin bridges to the service's /mcp endpoint:
Then set CLAUDEBOX_URL (and CLAUDEBOX_MCP_MODE_TOKEN if the server requires auth).
--permission-mode bypassPermissions is the adapter's default (modern equivalent of the pre-v2 --dangerously-skip-permissions). Claude has full, unrestricted access to the container. That's the entire point. Override per-request via RunRequest.extra_args./home/you/project is mounted at the same path inside the container. This means Docker volume mounts that Claude creates from within the container resolve correctly against host paths.claude user UID/GID is automatically adjusted to match the host directory owner on startup. File permissions should just work without manual chown.claude-<path> for interactive (TTY) sessions and claude-<path>_prog for programmatic (no TTY) sessions. Both share the same mounted volumes and data.telegram.yml config file. This is intentional to prevent accidentally exposing Claude to the public.claudebox --update when you want to update.WTFPL — do what the fuck you want to.