dhi.io is unreachable on the company network, blocking apk during build. Trivy scanning in CI provides vulnerability coverage in the meantime. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| claude | ||
| hooks | ||
| proxy | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| build.sh | ||
| CLAUDE.md | ||
| claude.sh | ||
| docker-compose.yml | ||
| launch.bat | ||
| launch.sh | ||
| README.md | ||
| setup.sh | ||
docker-claude
Runs Claude 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 (GUI) | Colima (CLI): brew install colima docker docker-compose && colima start |
| Linux | Docker Engine: curl -fsSL https://get.docker.com | sh |
Rancher Desktop |
| Windows | Rancher Desktop (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:
./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:./launch.shA 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:20-alpine), runs as the built-innodeuser (UID 1000), onclaude-internalonlyproxy— Squid forward proxy (alpine:3.21), bridgesclaude-internal↔ internet with egress allowlistclaude-internal—internal: true; no default gateway, containers cannot reach the internet directlyproxy-external— Standard bridge; proxy sidecar only
Prerequisites
A Docker runtime with Compose support. Choose a free, open-source option:
- macOS: Rancher Desktop or Colima
- Linux: Docker Engine CE (
curl -fsSL https://get.docker.com | sh) - Windows: Rancher Desktop 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
ANTHROPIC_API_KEY=sk-ant-...
Get a key at console.anthropic.com.
Option 2 — OAuth token (subscription, headless-friendly)
Run this on your host (not inside the container) to generate a 1-year token:
claude setup-token
Then paste the token into setup, or set it manually in .env:
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
./launch.sh # folder picker → starts Claude in the selected directory
CLI / power users
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)
- Install WSL2:
wsl --installin PowerShell - Open the Ubuntu terminal and run:
curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER - Log out and back in, then run
launch.batas usual.
Building locally
./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:
./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 |