# 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 Two containers managed by Docker Compose: - **`claude`** — Claude Code CLI (`node:24-alpine`), runs as the built-in `node` user (UID 1000), isolated to an internal-only Docker network - **`proxy`** — Squid forward proxy (`alpine:3.21`), `squid` user, 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` container physically cannot reach the internet without going through the `proxy` container. Auth supports three modes (checked at startup by `claude.sh`): - `ANTHROPIC_API_KEY` — API key - `CLAUDE_CODE_OAUTH_TOKEN` — 1-year token from `claude 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 `~/.claude` on the host. ## File Structure ``` docker-claude/ ├── claude.sh # Control script: start/stop/update/logs/status/shell ├── setup.sh # First-time setup wizard (Docker check + auth config) ├── launch.sh # Folder-picker launcher for macOS/Linux ├── launch.bat # Folder-picker launcher for Windows ├── build.sh # Build images locally (development) ├── docker-compose.yml # Service definitions and network topology ├── claude/ │ └── Dockerfile # Claude Code stable release (node:24-alpine, UID 1000) ├── proxy/ │ ├── Dockerfile # Squid proxy sidecar (alpine:3.21, squid user) │ └── squid.conf # Squid ACL config — egress allowlist lives here ├── hooks/ │ └── pre-commit # Enforces executable bit on shell scripts ├── .env.example # Template for credentials and options ├── .gitignore # Excludes .env and logs ├── .dockerignore # Keeps .env out of build context └── README.md # User documentation ``` ## Development Workflow ```bash ./setup.sh # first-time: configure Docker check + auth cd /path/to/project && ./claude.sh start # start proxy + launch Claude (pulls images, mounts CWD) ./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 all shell scripts. Activate it once after cloning: ```bash git config core.hooksPath hooks ``` ## Coding Standards - Shell scripts use `set -euo pipefail` - Dockerfiles use Alpine (`node:24-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-privileges` on all containers - `.env` is never committed (enforced by `.gitignore` and `.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: ```bash 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.bashrc` and `~/.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: ```bash 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