docker-claude/CLAUDE.md
docker-claude a566b463a9
Some checks failed
Build images / build-and-push (push) Blocked by required conditions
Build images / check-docker (push) Successful in 1s
Build images / scan (push) Has been cancelled
docs: update node:20-alpine references to node:24-alpine
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 15:17:15 +02:00

4.8 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

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

./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:

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:

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:

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