# docker-claude Runs [Claude Code](https://claude.ai/code) inside an isolated Docker environment with a proxy sidecar for controlled egress. Claude cannot access the host filesystem or network directly. ## Quick Start **1. Install a Docker runtime** Pick the free, open-source option for your platform: | Platform | Recommended | Alternative | |---|---|---| | macOS | [Rancher Desktop](https://rancherdesktop.io/) (GUI) | [Colima](https://github.com/abiosoft/colima) (CLI): `brew install colima docker docker-compose && colima start` | | Linux | Docker Engine: `curl -fsSL https://get.docker.com \| sh` | [Rancher Desktop](https://rancherdesktop.io/) | | Windows | [Rancher Desktop](https://rancherdesktop.io/) (GUI) | WSL2 + Docker Engine (see below) | > **Note:** Docker Desktop is not listed — it requires a commercial licence for business use. **2. Download this repo** Clone or download and unzip this repository somewhere on your machine. **3. Run setup** - **macOS / Linux:** Open a terminal, navigate to the folder, and run: ```bash ./setup.sh ``` - **Windows:** Double-click `launch.bat` — it will run setup automatically on first launch. Setup will ask how you want to authenticate (API key, subscription token, or browser login) and save your settings. **4. Start Claude** - **macOS / Linux:** Double-click `launch.sh`, or run it from a terminal: ```bash ./launch.sh ``` A folder picker will appear — select the project you want Claude to work on. - **Windows:** Double-click `launch.bat`. --- ## Architecture ``` ┌──────────────────────────────────────────────────────────┐ │ Host machine │ │ │ │ claude.sh (control script) │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ Docker: claude-secure │ │ │ │ │ │ │ │ ┌─────────────┐ claude-internal │ │ │ │ │ claude │ (internal: true) │ │ │ │ │ (UID 1000) │──────────────► ┌──────────┐ │ │ │ │ └─────────────┘ │ proxy │ │ │ │ │ │ (UID 13) │ │ │ │ │ └────┬─────┘ │ │ │ │ proxy-external │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ internet (allowlisted) │ └──────────────────────────────────────────────────────────┘ ``` - **`claude`** — Claude Code CLI (`node:24-alpine`), runs as the built-in `node` user (UID 1000), on `claude-internal` only - **`proxy`** — Squid forward proxy (`alpine:3.21`), bridges `claude-internal` ↔ internet with egress allowlist - **`claude-internal`** — `internal: true`; no default gateway, containers cannot reach the internet directly - **`proxy-external`** — Standard bridge; proxy sidecar only ## Prerequisites A Docker runtime with Compose support. Choose a free, open-source option: - **macOS:** [Rancher Desktop](https://rancherdesktop.io/) or [Colima](https://github.com/abiosoft/colima) - **Linux:** [Docker Engine CE](https://docs.docker.com/engine/install/) (`curl -fsSL https://get.docker.com | sh`) - **Windows:** [Rancher Desktop](https://rancherdesktop.io/) or WSL2 + Docker Engine > Docker Desktop is not recommended — it requires a commercial licence for business use. ## Authentication Three options — `./setup.sh` will guide you through picking one: ### Option 1 — API key ```bash ANTHROPIC_API_KEY=sk-ant-... ``` Get a key at [console.anthropic.com](https://console.anthropic.com/settings/keys). ### Option 2 — OAuth token (subscription, headless-friendly) Run this **on your host** (not inside the container) to generate a 1-year token: ```bash claude setup-token ``` Then paste the token into setup, or set it manually in `.env`: ```bash CLAUDE_CODE_OAUTH_TOKEN=... ``` ### Option 3 — Browser OAuth (interactive) Leave both keys unset. On first run, Claude Code will print a login URL. Port 54545 must be reachable from your browser for the OAuth callback. ## Usage ### Normal use ```bash ./launch.sh # folder picker → starts Claude in the selected directory ``` ### CLI / power users ```bash cd ~/myproject ./claude.sh start ./claude.sh stop # Stop and remove all containers ./claude.sh update # Pull latest images from the registry ./claude.sh logs # Tail proxy logs ./claude.sh status # Show container status ./claude.sh shell # Debug bash shell in the Claude container ``` ### Windows: WSL2 + Docker Engine (alternative to Rancher Desktop) 1. Install [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install): `wsl --install` in PowerShell 2. Open the Ubuntu terminal and run: ```bash curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER ``` 3. Log out and back in, then run `launch.bat` as usual. ### Building locally ```bash ./build.sh # build with layer cache ./build.sh --no-cache # force full rebuild ``` ## Egress allowlist Edit `proxy/squid.conf` and add domains to the `allowed_sites` ACL: ``` acl allowed_sites dstdomain api.anthropic.com acl allowed_sites dstdomain statsig.anthropic.com # acl allowed_sites dstdomain api.github.com # acl allowed_sites dstdomain registry.npmjs.org ``` Rebuild after changes: ```bash ./claude.sh stop && ./claude.sh start ``` ## Security controls | Control | claude | proxy | |---|---|---| | Non-root user | UID 1000 (`node`, built into base image) | `squid` user | | `no-new-privileges` | yes | yes | | All capabilities dropped | yes | yes | | Direct internet access | no (`internal` network only) | allowlisted only | | Host filesystem | CWD mounted as `/workspace` | none | | Docker socket | not mounted | not mounted |