5 KiB
Project Guidance
This file provides context and guidance for working with this project.
Project Overview
docker-claude runs Claude Code inside a hardened Docker environment with a Squid proxy sidecar. The goal is full host encapsulation: Claude cannot access the host filesystem or network. All egress is routed through an allowlist-enforcing proxy.
Architecture
Three containers managed by Docker Compose:
claude— Claude Code CLI (node:20-alpine), runs as the built-innodeuser (UID 1000), isolated to an internal-only Docker networkwebui— Claude Code as a browser terminal via ttyd (node:20-alpine),nodeuser (UID 1000), same network isolation, basic auth requiredproxy— Squid forward proxy (alpine:3.21),squiduser, bridges the internal network to the internet with an egress allowlist
Key Docker network property: claude-internal has internal: true, meaning Docker adds no default gateway. The claude and webui containers physically cannot reach the internet without going through the proxy container.
The webui service reuses claude/Dockerfile. Its entrypoint (claude/webui-entrypoint.sh) starts ttyd --credential user:pass claude instead of claude directly.
Auth supports three modes (checked at startup by claude.sh):
ANTHROPIC_API_KEY— API keyCLAUDE_CODE_OAUTH_TOKEN— 1-year token fromclaude setup-token(headless-friendly)- Neither set — Claude Code prompts for browser login on first run; port 54545 is published for the OAuth callback. Credentials persist in the
claude-confignamed volume.
File Structure
docker-claude/
├── claude.sh # Control script: start/stop/run/web/web-stop/update/logs/status/shell
├── docker-compose.yml # Service definitions and network topology
├── claude/
│ ├── Dockerfile # Claude Code + ttyd (node:20-alpine, UID 1000)
│ └── webui-entrypoint.sh # Entrypoint for webui: starts ttyd wrapping claude
├── proxy/
│ ├── Dockerfile # Squid proxy sidecar (alpine:3.21, squid user)
│ └── squid.conf # Squid ACL config — egress allowlist lives here
├── .env.example # Template for ANTHROPIC_API_KEY, WEBUI_PASSWORD, etc.
├── .gitignore # Excludes .env and logs
├── .dockerignore # Keeps .env out of build context
└── README.md # User documentation
Development Workflow
chmod +x claude.sh build.sh
cp .env.example .env # set ANTHROPIC_API_KEY (and WEBUI_PASSWORD for web mode)
cd /path/to/project && ./claude.sh start # start proxy + launch Claude (pulls images, mounts CWD)
./claude.sh web # start proxy + webui (browser terminal on :7681)
./claude.sh update # pull latest images from registry
./build.sh # build images locally (development)
Git Hooks
A pre-commit hook lives in hooks/ and enforces the executable bit on claude.sh and build.sh. Activate it once after cloning:
git config core.hooksPath hooks
Coding Standards
- Shell scripts use
set -euo pipefail - Dockerfiles use Alpine (
node:20-alpine,alpine:3.21) for minimal attack surface - Alpine packages use
apk add --no-cache; no apt cache cleanup layer needed - No capabilities granted;
no-new-privilegeson all containers .envis never committed (enforced by.gitignoreand.dockerignore)- Commit messages follow Angular format:
type(scope): summary
Extending the Egress Allowlist
Add domains to proxy/squid.conf under the allowed_sites ACL, then rebuild:
docker compose -p claude-secure build proxy
./claude.sh stop && ./claude.sh start
Environment Persistence
This sandbox has a persistent environment file at /etc/sandbox-persistent.sh.
This file is automatically sourced in all shell contexts:
- Non-interactive shells: via
BASH_ENV=/etc/sandbox-persistent.sh - Login shells: via
/etc/profile.d/sandbox-persistent.sh - Interactive shells: via
/etc/bash.bashrcand~/.bashrc
Critical: Shell Completions Must NOT Be in the Persistent Environment File
NEVER add shell completion scripts to /etc/sandbox-persistent.sh.
Shell completion scripts will completely break the bash tool when sourced via the persistent environment file.
Network access
There is a firewall in place to restrict outbound network access. If you need http/https access to an external service, request it by running:
sbx policy allow network [domain]
Git Authentication
The sandbox proxy handles GitHub authentication automatically by injecting credentials for HTTPS Git operations.
Additional Notes
- Always read relevant files before making changes
- Run tests after making modifications
- Follow the existing code structure and patterns
- You have sudo permissions, so you can install necessary packages
- npm, pip and uv are already available for package management