2.1 KiB
2.1 KiB
CLAUDE.md
Quick context for Claude Code. See README.md for full details, ARCHITECTURE.md for technical deep-dives, USECASES.md for expected behaviors.
Key files
scripts/bootstrap.sh-- First-time server setup (manual, uses Bitwarden)scripts/configure.sh-- Idempotent server config (firewall, certbot, start services; CI-safe)scripts/deploy.sh-- SSH-triggered deploy + cert issuance + provision (deploy-, cert-, provision commands)tools/new-app.sh-- Single-command new static site (DNS + Gitea repo + cert + bucket + deploy + verify)tools/new-service.sh-- Scaffold a new Docker Compose service (compose + workflow)tools/remove-app.sh-- Remove a static site (local files + Gitea repo)docker/nginx/conf.d/-- Per-app nginx server blocksdocker/<domain>/compose.yml-- Per-app compose filesdocker/garage/-- Garage S3 object storage (Dockerfile, garage.toml, .env.keys).gitea/workflows/-- Per-app deploy workflows + provision.yml
Conventions
- App name = domain (e.g.,
example.com) - Container name = dots → underscores (e.g.,
example_com) - One domain per conf file -- deploy.sh derives cert name from filename
- All HTTP → HTTPS; bare domain →
www.<domain> - All shell scripts use
set -euo pipefailand must be idempotent - The
sharedDocker network is created by nginx compose and used by all apps - Secrets are in Bitwarden Secrets Manager (see README.md for full list)
- Service secrets use
.env.keysfiles (see README.md)
Deploy flow
- App repo push →
build.yml→ build/push image → SSHdeploy-<domain>→ deploy.sh - This repo push →
deploy-<app>.yml(path match) → SSHdeploy-<app>→ deploy.sh - Setup change →
provision.yml→ SSHprovision→ configure.sh
Build and test
No build step. No tests. Verify changes by:
- Reading scripts and checking idempotency
- Walking through each use case in USECASES.md
- Cross-checking docs against scripts
Commit style
- Short, lowercase commit messages (e.g., "add example.com", "fix deploy command")
- Do NOT include "Co-Authored-By" lines
- Commit only when explicitly asked