docker-claude/docker-compose.yml

111 lines
3.8 KiB
YAML
Raw Normal View History

2026-04-14 20:11:24 +02:00
services:
# ─── Proxy sidecar ─────────────────────────────────────────────────────────
# Bridges the isolated internal network to the internet.
# Enforces an egress allowlist — see proxy/squid.conf.
proxy:
build:
context: proxy
dockerfile: Dockerfile
2026-04-14 20:11:24 +02:00
networks:
- claude-internal # reachable by claude and webui containers
- proxy-external # has outbound internet access
2026-04-14 20:11:24 +02:00
restart: unless-stopped
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
tmpfs:
- /tmp
- /var/cache/squid
2026-04-14 20:11:24 +02:00
- /var/log/squid
# ─── Claude Code CLI container ─────────────────────────────────────────────
2026-04-14 20:11:24 +02:00
# No direct internet access. All egress routes through the proxy sidecar.
# Run via "docker compose run --rm --service-ports claude" (managed by claude.sh).
2026-04-14 20:11:24 +02:00
claude:
build:
context: claude/
dockerfile: Dockerfile
2026-04-14 20:11:24 +02:00
depends_on:
proxy:
condition: service_healthy
networks:
- claude-internal # only — no route to the internet
2026-04-14 20:11:24 +02:00
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN:-}
2026-04-14 20:11:24 +02:00
- HTTP_PROXY=http://proxy:3128
- HTTPS_PROXY=http://proxy:3128
- ALL_PROXY=http://proxy:3128
- NO_PROXY=localhost,127.0.0.1
ports:
# OAuth callback — required for browser-based login (claude login)
- "0.0.0.0:54545:54545"
volumes:
- claude-config:/home/node/.claude
# Workspace is injected by claude.sh via --volume flag at run time.
# Default: named Docker volume. Override: set WORKSPACE_DIR on the host.
2026-04-14 20:11:24 +02:00
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
stdin_open: true
tty: true
# ─── Claude Code web interface ─────────────────────────────────────────────
# Serves Claude Code as a browser terminal via ttyd (port 7681).
# Protected by HTTP basic auth — set WEBUI_USER / WEBUI_PASSWORD in .env.
# Network isolation is identical to the CLI container.
webui:
build:
context: claude/
dockerfile: Dockerfile
entrypoint: ["/usr/local/bin/webui-entrypoint.sh"]
depends_on:
proxy:
condition: service_healthy
networks:
- claude-internal # only — no route to the internet
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN:-}
- HTTP_PROXY=http://proxy:3128
- HTTPS_PROXY=http://proxy:3128
- ALL_PROXY=http://proxy:3128
- NO_PROXY=localhost,127.0.0.1
- WEBUI_USER=${WEBUI_USER:-claude}
- WEBUI_PASSWORD=${WEBUI_PASSWORD:-}
- WEBUI_PORT=7681
ports:
- "0.0.0.0:7681:7681"
# OAuth callback — required for browser-based login (claude login)
- "0.0.0.0:54545:54545"
volumes:
- claude-config:/home/node/.claude
- claude-web-workspace:/workspace
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
stdin_open: true
tty: true
restart: unless-stopped
2026-04-14 20:11:24 +02:00
networks:
# Internal-only: Docker adds no default gateway → no direct internet route
claude-internal:
driver: bridge
internal: true
# External: standard bridge with internet access (proxy only)
proxy-external:
driver: bridge
volumes:
# Persists Claude Code auth credentials (~/.claude/) across container runs.
# Shared between the CLI and web interface so login carries over.
claude-config:
# Persistent workspace for the web interface
claude-web-workspace: