{"id":49482650,"url":"https://github.com/psyb0t/docker-claudebox","last_synced_at":"2026-07-05T05:01:30.781Z","repository":{"id":298986562,"uuid":"1001753343","full_name":"psyb0t/docker-claudebox","owner":"psyb0t","description":"Claude Code in Docker. Drop-in OpenAI-compatible API, MCP server, Telegram bot, and CLI — five interfaces, one image. Persistent sessions, file ops, always-on skill injection, and a full dev toolchain (Go, Python, Node, K8s, Terraform, databases) or a minimal image with just the basics.","archived":false,"fork":false,"pushed_at":"2026-07-04T07:47:31.000Z","size":355,"stargazers_count":16,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-07-04T09:25:34.825Z","etag":null,"topics":["ai","ai-agent","api","claude","claude-code","code-agent","container","development-agent","docker","docker-image","multimodal-agent","programmatic","telegram","web-api","wrapper"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/psyb0t.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"psyb0t","custom":["https://github.com/psyb0t/sponsors#monero-xmr"]}},"created_at":"2025-06-14T00:32:36.000Z","updated_at":"2026-07-04T07:47:32.000Z","dependencies_parsed_at":"2025-07-09T13:44:55.964Z","dependency_job_id":"24b74dd3-95d0-452f-a776-c494b2ae3421","html_url":"https://github.com/psyb0t/docker-claudebox","commit_stats":null,"previous_names":["psyb0t/docker-claude-code","psyb0t/docker-claudebox"],"tags_count":90,"template":false,"template_full_name":null,"purl":"pkg:github/psyb0t/docker-claudebox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-claudebox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-claudebox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-claudebox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-claudebox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/psyb0t","download_url":"https://codeload.github.com/psyb0t/docker-claudebox/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psyb0t%2Fdocker-claudebox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35143802,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","ai-agent","api","claude","claude-code","code-agent","container","development-agent","docker","docker-image","multimodal-agent","programmatic","telegram","web-api","wrapper"],"created_at":"2026-04-30T23:04:41.294Z","updated_at":"2026-07-05T05:01:30.760Z","avatar_url":"https://github.com/psyb0t.png","language":"Shell","funding_links":["https://github.com/sponsors/psyb0t","https://github.com/psyb0t/sponsors#monero-xmr"],"categories":[],"sub_categories":[],"readme":"# claudebox\n\n[![Docker Hub](https://img.shields.io/docker/pulls/psyb0t/claudebox?style=flat-square)](https://hub.docker.com/r/psyb0t/claudebox)\n[![License: WTFPL](https://img.shields.io/badge/License-WTFPL-brightgreen.svg?style=flat-square)](http://www.wtfpl.net/)\n\nA runtime harness for [Claude Code](https://claude.com/product/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.\n\n\u003e **v2.0.0 — rebased on `psyb0t/aicodebox`.** claudebox is now a thin child image of the shared aicodebox base (same pattern as `psyb0t/pibox`). Every mode surface (API / Telegram / Cron / MCP) is inherited from the base and stays in lockstep with future base fixes. See [`CHANGELOG.md`](CHANGELOG.md) for the full migration guide (endpoint shape changes, env-var namespace, path renames — all mitigated by aliases + symlinks so existing configs keep working).\n\n**Runtime hardening (recommended `docker run` flags):**\n- `--cap-drop=ALL --cap-add=NET_BIND_SERVICE` — drop every Linux capability, add back only bind-below-1024 if you actually need it.\n- `--security-opt no-new-privileges:true` — block setuid privilege escalation inside the container.\n- `--memory=2g --cpus=2 --pids-limit=512` — cap runtime resource use so a runaway process can't starve the host.\n- `--read-only --tmpfs /tmp:rw,noexec,nosuid` (only if you don't use `/workspace` for writes — otherwise skip).\nThe 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`.\n\nclaudebox wraps Claude Code with several distinct interfaces:\n\n- **Interactive CLI** — a drop-in replacement for the native `claude` command, with persistent containers and automatic session resumption across runs\n- **Programmatic CLI** — non-interactive mode for scripts, CI/CD pipelines, and automation; pass a prompt, get structured output, pipe it wherever you need\n- **HTTP API server** — a full REST API with workspace management, file operations, structured output formats, and workspace isolation for multi-tenant deployments\n- **OpenAI-compatible endpoint** — a `chat/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 handling\n- **MCP server** — a [Model Context Protocol](https://modelcontextprotocol.io/) endpoint over streamable HTTP so other AI agents and tools (Claude Desktop, other Claude Code instances, etc.) can use Claude Code as a tool\n- **Telegram bot** — a conversational interface with per-chat workspaces, configurable models and effort levels, file sharing, shell access, and group chat support\n- **Cron scheduler** — yaml-defined Claude jobs running on cron schedules with per-job activity history, sub-minute resolution, and overlap protection\n\nBeyond 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.\n\n\u003e **Renamed from `docker-claude-code`:** This project was previously called `docker-claude-code` with the Docker image at `psyb0t/claude-code`. Starting with v1.0.0, it is `claudebox` — the Docker image is now `psyb0t/claudebox`, the default binary name is `claudebox`, the GitHub repository is `psyb0t/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.\n\n## Table of Contents\n\n- [Requirements](#requirements)\n- [Quick Start](#quick-start)\n- [Image Variants](#image-variants)\n- [What's Inside (Full Image)](#whats-inside-full-image)\n- [Authentication](#authentication)\n- [Modes](#modes)\n- [Configuration](#configuration)\n- [Gotchas](#gotchas)\n- [License](#license)\n\n## Requirements\n\nDocker installed and running. That's it.\n\n## Quick Start\n\n### One-liner install\n\nThe 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.\n\n```bash\n# minimal image — default; Claude installs what it needs on the fly\ncurl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh | bash\n\n# full image — every dev tool pre-installed (Go, Python, kubectl, terraform, ...)\nexport CLAUDEBOX_FULL=1 \u0026\u0026 curl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh | bash\n\n# custom binary name (e.g. if you want to call it 'claude' instead of 'claudebox')\ncurl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh | bash -s -- claude\n# or: export CLAUDEBOX_BIN_NAME=claude \u0026\u0026 curl -fsSL .../install.sh | bash\n```\n\n\u003e **v2 note:** the variant naming flipped in v2. `latest` is now the minimal image (was the full image pre-v2); `latest-full` is the toolchain-loaded variant (was `latest` pre-v2). The `CLAUDEBOX_MINIMAL=1` opt-in from v1 is now a no-op — you already get minimal by default. Set `CLAUDEBOX_FULL=1` to opt into the toolchain image.\n\n\u003e **Heads up on env vars:** `VAR=x curl … | bash` does **not** set `VAR` for the install script — bash semantics attach the var to `curl` only. Always `export` the var first (or put it on the `bash` side of the pipe).\n\n### Manual setup\n\nIf you prefer not to pipe scripts to bash:\n\n```bash\n# 1. create the data directory\nmkdir -p ~/.claude\n\n# 2. create SSH keys for git operations inside the container\nmkdir -p \"$HOME/.ssh/claudebox\"\nssh-keygen -t ed25519 -C \"claude@claude.ai\" -f \"$HOME/.ssh/claudebox/id_ed25519\" -N \"\"\n# then add the public key to GitHub/GitLab/wherever you push code\n\n# 3. pull the image\ndocker pull psyb0t/claudebox:latest        # minimal (default)\n# or: docker pull psyb0t/claudebox:latest-full   # toolchain-loaded variant\n\n# 4. grab the wrapper script and install it\n# see install.sh for exactly how the wrapper is set up\n```\n\n## Image Variants\n\n### `psyb0t/claudebox:latest` (minimal, default)\n\nThe default v2 image. Just enough to run Claude Code on top of the aicodebox base: Ubuntu 24.04, git/curl/wget/jq, Node.js 22 LTS + npm, Python 3.12 + 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.\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh | bash\n```\n\nUse `/aicodebox-init.d/*.sh` hooks (see [Init Hooks](docs/customization.md#init-hooks-claudeinitd)) to pre-install your tools on first container create so Claude doesn't burn tokens figuring out package management.\n\n### `psyb0t/claudebox:latest-full` (toolchain-loaded)\n\nEverything pre-installed. Layered on top of the minimal image: Go 1.26, Python 3.12.11 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.\n\n```bash\nexport CLAUDEBOX_FULL=1 \u0026\u0026 curl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh | bash\n```\n\n### Comparison\n\n|                                       | `latest` (minimal) | `latest-full` |\n| ------------------------------------- | :----------------: | :-----------: |\n| Ubuntu 24.04                          |       yes       |       yes        |\n| git, curl, wget, jq                   |       yes       |       yes        |\n| Node.js LTS + npm                     |       yes       |       yes        |\n| Docker CE + Compose                   |       yes       |       yes        |\n| Claude Code CLI                       |       yes       |       yes        |\n| Go 1.26.1 + tools                     |       yes       |        -         |\n| Python 3.12.11 + tools                |       yes       |        -         |\n| Node.js dev tools                     |       yes       |        -         |\n| C/C++ tools                           |       yes       |        -         |\n| DevOps (terraform, kubectl, helm, gh) |       yes       |        -         |\n| Database clients                      |       yes       |        -         |\n| Shell utilities (ripgrep, bat, etc.)  |       yes       |        -         |\n\n## What's Inside (Full Image)\n\n**Languages and runtimes:**\n\n- **Go 1.26.1** with the full toolchain — golangci-lint, gopls, delve, staticcheck, gofumpt, gotests, impl, gomodifytags\n- **Python 3.12.11** via pyenv — flake8, black, isort, autoflake, pyright, mypy, vulture, pytest, poetry, pipenv, plus common libraries (requests, beautifulsoup4, lxml, pyyaml, toml)\n- **Node.js LTS** — eslint, prettier, typescript, ts-node, yarn, pnpm, nodemon, pm2, framework CLIs (React, Vue, Angular), newman, http-server, serve, lighthouse, storybook\n- **C/C++** — gcc, g++, make, cmake, clang-format, valgrind, gdb, strace, ltrace\n\n**DevOps and infrastructure:**\n\n- Docker CE with Docker Compose (docker-in-docker support)\n- Terraform, kubectl, helm, GitHub CLI (`gh`)\n\n**Database clients:**\n\n- sqlite3, postgresql-client (`psql`), mysql-client, redis-tools (`redis-cli`)\n\n**Shell and system utilities:**\n\n- jq, tree, ripgrep, bat, exa, fd-find, ag (silversearcher), htop, tmux, shellcheck, shfmt, httpie, vim, nano\n- Archive tools (zip, unzip, tar), networking (net-tools, iputils-ping, dnsutils)\n\n**Container automation:**\n\n- Auto-generated `CLAUDE.md` in each workspace listing all available tools, so Claude knows what it has access to\n- Git identity auto-configured from environment variables\n- Claude Code CLI with auto-updates disabled by default (opt in with `--update`)\n- Workspace trust dialog pre-accepted — no interactive prompts\n- Custom scripts via `~/.claude/bin` (added to PATH automatically)\n- Init hooks via `~/.claude/init.d/*.sh` (run once on first container create)\n- Always-active skills via `~/.claude/.always-skills/` (injected into every invocation)\n- Session continuity via `--continue` / `--no-continue` / `--resume \u003csession_id\u003e`\n- Structured JSON debug logging with `DEBUG=true`\n\n## Authentication\n\nYou need either an Anthropic API key or an OAuth token. Set up once, use everywhere:\n\n```bash\n# interactive OAuth token setup (one-time)\nclaudebox setup-token\n\n# then use the token for programmatic and headless runs\nCLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-xxx claudebox \"do stuff\"\n\n# or use an API key directly\nANTHROPIC_API_KEY=sk-ant-api03-xxx claudebox \"do stuff\"\n```\n\n## Modes\n\nclaudebox 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.\n\n### [Interactive Mode →](docs/modes/interactive.md)\n\nDrop-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`.\n\n```bash\nclaudebox\n```\n\n### [Programmatic Mode →](docs/modes/programmatic.md)\n\nNon-interactive prompt → response for scripts, pipelines, and automation. Plain text, JSON, JSON-verbose (with full tool-call history), and stream-json output formats. Model selection, system prompt overrides, JSON-schema-constrained output, session continuation.\n\n```bash\nclaudebox \"explain this codebase\" --output-format json --model haiku\n```\n\n### [API Mode →](docs/modes/api.md)\n\nRun 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](https://modelcontextprotocol.io/) endpoint over streamable HTTP so other agents can use Claude Code as a tool.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_API_MODE=1\n  - CLAUDEBOX_API_MODE_TOKEN=your-secret-token\n```\n\n### [Telegram Mode →](docs/modes/telegram.md)\n\nTalk 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, `/bash`, `/fetch`, `/cancel`, `/status`, `/config`, `/reload` commands, and `[SEND_FILE: path]` for Claude to send files back.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_TELEGRAM_MODE=1\n  - CLAUDEBOX_TELEGRAM_MODE_TOKEN=...\n```\n\n### [Cron Mode →](docs/modes/cron.md)\n\nYAML-defined scheduled jobs. Standard 5-field cron or 6-field for sub-minute resolution. Per-job stream-json history under `~/.claude/cron/history/\u003cworkspace-slug\u003e/\u003cts\u003e-\u003cjob\u003e/`, 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.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_CRON_MODE=1\n  - CLAUDEBOX_CRON_MODE_FILE=/home/aicode/.claude/cron.yaml\n```\n\n## Configuration\n\n- **[Environment variables →](docs/environment-variables.md)** — full table of `CLAUDEBOX_*` settings the wrapper and entrypoint understand, plus `CLAUDEBOX_ENV_*` (forward arbitrary vars into the container) and `CLAUDEBOX_MOUNT_*` (extra volume mounts).\n- **[Customization →](docs/customization.md)** — extend Claude's container with custom scripts (`~/.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`).\n\n## Gotchas\n\n- **`--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`.\n- **SSH keys** are mounted from the host for git push/pull inside the container. Do not share your container or image with untrusted parties.\n- **Host paths are preserved** — your project at `/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.\n- **UID/GID matching** — the container's `claude` user UID/GID is automatically adjusted to match the host directory owner on startup. File permissions should just work without manual `chown`.\n- **Docker-in-Docker** — the Docker socket is mounted into the container. Claude can build images and run containers from within its container. This is by design.\n- **Two containers per workspace** — the wrapper creates `claude-\u003cpath\u003e` for interactive (TTY) sessions and `claude-\u003cpath\u003e_prog` for programmatic (no TTY) sessions. Both share the same mounted volumes and data.\n- **Workspace busy tracking** — in API mode, each workspace can only have one active Claude process at a time. Concurrent requests to the same workspace return a 409 Conflict response. Use different workspace subpaths for parallel work.\n- **Telegram config is required** — the Telegram bot will not start without a `telegram.yml` config file. This is intentional to prevent accidentally exposing Claude to the public.\n- **Auto-updates disabled** — Claude Code CLI auto-updates are disabled by default inside the container to ensure reproducible behavior. Opt in with `claudebox --update` when you want to update.\n\n## License\n\n[WTFPL](http://www.wtfpl.net/) — do what the fuck you want to.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsyb0t%2Fdocker-claudebox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpsyb0t%2Fdocker-claudebox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsyb0t%2Fdocker-claudebox/lists"}