Update CLAUDE.md with installer and release workflow documentation

- Quick Start: add pre-built install section with curl one-liner
- Directory Structure: expand scripts/ with all deployment scripts
- Registry Operations: add build-release, install commands, two-compose note
- V2 Gotchas: document release vs source detection, api/dist gitignore,
  api/.dockerignore purpose
- Key Config Files: add docker-compose.prod.yml and config.sh

Bunker Admin
This commit is contained in:
bunker-admin 2026-03-22 20:38:36 -06:00
parent 8e6f0996de
commit a71ba20176

View File

@ -188,7 +188,15 @@ changemaker.lite/
├── media-manager/ # Legacy media manager (reference)
├── nginx/ # Reverse proxy config (subdomain routing + CSP)
├── configs/ # Prometheus, Grafana, Alertmanager configs
├── scripts/ # backup.sh, legacy Cloudflare scripts
├── scripts/ # Deployment, backup, upgrade, registry scripts
│ ├── install.sh # Curl-friendly installer (downloads tarball + runs config.sh)
│ ├── build-and-push.sh # Build production images → push to Gitea registry
│ ├── build-release.sh # Package runtime files into release tarball
│ ├── mirror-images.sh # Mirror third-party images to Gitea
│ ├── upgrade.sh # 6-phase upgrade (git or release-tarball mode)
│ ├── upgrade-check.sh # Check for updates (git or Gitea API)
│ ├── upgrade-watcher.sh # Systemd bridge for admin GUI upgrades
│ └── backup.sh # PostgreSQL + Listmonk + uploads backup
├── docker-compose.yml # V2 orchestration (20+ services)
├── docker-compose.v1.yml # V1 backup (reference)
├── .env.example # All required environment variables
@ -199,7 +207,23 @@ changemaker.lite/
## Quick Start Guide
### Initial Setup (First Time)
### Pre-built Install (Production — Recommended)
The fastest way to deploy. No source code, no compilation:
```bash
curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/v2/scripts/install.sh | bash
```
This downloads a ~9MB release tarball, runs the config wizard, and sets `IMAGE_TAG=latest`. Then:
```bash
cd ~/changemaker.lite && docker compose up -d
```
Pre-built images are pulled from `gitea.bnkops.com/admin` (~2 min). Database migrations and seeding run automatically via the API entrypoint. Access the admin GUI at http://localhost:3000.
### Source Install (Development)
1. **Clone repository and checkout v2 branch:**
```bash
@ -330,6 +354,36 @@ docker compose exec api npx drizzle-kit push
docker compose down
```
### Registry & Release Operations
```bash
# Build production images and push to Gitea registry
./scripts/build-and-push.sh --services api,admin,media-api,nginx
./scripts/build-and-push.sh --no-push # Build only, no push (verify)
# Mirror third-party images to Gitea
./scripts/mirror-images.sh # Core images (postgres, redis, etc.)
./scripts/mirror-images.sh --all # Include heavy images (RC, Jitsi, n8n)
# Build release tarball (for pre-built installs — run AFTER build-and-push)
./scripts/build-release.sh --tag v2.1.0 # Creates releases/changemaker-lite-v2.1.0.tar.gz
./scripts/build-release.sh --tag v2.1.0 --upload # Also upload to Gitea Releases API
./scripts/build-release.sh --dry-run # Preview tarball contents
# Use registry images in upgrade (source installs)
./scripts/upgrade.sh --use-registry --force --skip-backup
# Install from tarball (end-user one-liner)
curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/v2/scripts/install.sh | bash
```
**Two compose files:**
- `docker-compose.yml` — Development: includes `build:` blocks and `./api:/app` source mounts
- `docker-compose.prod.yml` — Production: `image:` only, no source mounts, `IMAGE_TAG:-latest`
Release tarballs ship `docker-compose.prod.yml` as the compose file. Source installs use `docker-compose.yml`.
**Note:** gitea.bnkops.com must use Pangolin tunnel (not Cloudflare proxy) for large image layers (>100MB). See `docs/REGISTRY_GUIDE.md`.
### Testing & Backup
```bash
# Media API tests
@ -626,6 +680,13 @@ cd api && npx tsc --noEmit && cd ../admin && npx tsc --noEmit
- MkDocs port 4003 (was 4000, conflicted with API)
- Media upload: requires separate RW volume mount for inbox directory (`:rw` on `/media/local/inbox`), library remains read-only
- FFmpeg/FFprobe: installed in media-api container (Alpine `apk add --no-cache ffmpeg`), used for metadata extraction
- **Registry mode:** `IMAGE_TAG=local` (default) never pulls from registry; set to a commit SHA or `latest` to use pre-built images; `--use-registry` in upgrade.sh auto-sets `IMAGE_TAG` to the new commit SHA
- **Registry auth:** `docker login gitea.bnkops.com` required once per machine; `GITEA_REGISTRY_USER`/`GITEA_REGISTRY_PASS` in `.env` used by the API's registry status endpoint only (not Docker itself)
- **Cloudflare + registry:** gitea.bnkops.com must be DNS-only (no proxy) to push image layers >100MB; Cloudflare free plan blocks large blobs with 413 errors. See `docs/REGISTRY_GUIDE.md`
- **Production image size:** API Dockerfile production stage uses `npm ci --omit=dev` + `npx prisma generate` (not copying from build stage) to avoid including TypeScript devDeps in the final image
- **Release vs source installs:** Detected by `VERSION` file + absence of `.git/`. Release installs use `docker-compose.prod.yml` (no build blocks, no source mounts, `IMAGE_TAG:-latest`). Source installs use `docker-compose.yml` (build blocks + source mounts for dev). `config.sh`, `upgrade.sh`, and `upgrade-check.sh` all auto-detect the mode
- **`api/dist/` is gitignored:** Compiled output must NOT be committed. It's generated by `npm run build` (dev) or baked into Docker images (prod). If root-owned (from container builds), fix with `docker run --rm -v ./api:/api alpine chown -R $(id -u):$(id -g) /api/dist/`
- **`api/.dockerignore` excludes dist/:** Prevents stale local compiled JS from being copied into Docker build context. Without this, cached Docker layers may serve old module sets even after adding new TypeScript modules
---
@ -757,8 +818,10 @@ V1 code archived in `influence/`, `map/`, and `docker-compose.v1.yml`. Two indep
## Key Configuration Files
### Infrastructure
- `docker-compose.yml` — V2 orchestration (20+ services, monitoring profile)
- `docker-compose.yml` — Development orchestration (build blocks + source mounts, 20+ services)
- `docker-compose.prod.yml` — Production orchestration (image-only, no source mounts, `IMAGE_TAG:-latest`)
- `.env` / `.env.example` — Environment variables (100+ vars)
- `config.sh` — Interactive setup wizard (14 steps, release-mode aware)
### Database
- `api/prisma/schema.prisma` — Main schema (30+ Prisma models)