Files
craftvia/docs/_certvia-archiv/DEPLOY-PROD-PREBUILT.md
T
msolarczekandClaude Opus 5 cadaedc6cc L10b Betrieb & Aufräumen: Deploy – craftvia-worker, CI-Testjob, DEPLOY.md, Certvia-Doku archiviert
- docker-compose.coolify(.prebuilt).yml: Service craftvia-worker (Target worker, Chromium,
  shm_size 1gb, gleiche Härtung), Craftvia-Variablen für app und worker.
- Dockerfile: worker-Stage mit HOME=/home/app (Chromium-Profil für non-root); lokaler
  docker build der Targets runner und worker erfolgreich, PDF-Erzeugung im Image geprüft.
- .env.example/.env.prod.example/.env.coolify.example: alle Craftvia-Variablen inkl. RLS,
  KI-Provider, PDF_CHROMIUM_PATH, OFFLINE_MAX_DAYS, API_RATE_LIMIT_*, AI_GENERATION_RETENTION_DAYS,
  AI_MONTHLY_TOKEN_LIMIT.
- CI (.github, .gitea): Job gate mit Postgres (pgvector) und Redis als Service: migrate deploy,
  seed, Passwort für craftvia_app, tsc, lint, build, npm run test.
- docs/craftvia/DEPLOY.md (aus den Certvia-Deploy-Docs abgeleitet): Architektur, Domains, Secrets,
  Worker, Migrationen, RLS-Aktivierung, Backup/Restore, KI, Rate Limits, Aufbewahrung, Smoke,
  Update/Rollback. build-and-push-images.sh baut craftvia-worker.
- Certvia-/ISMS-Dokumente aus docs/ nach docs/_certvia-archiv/ (mit README); Verweise in README.md
  und Skript-Kommentaren angepasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00

4.3 KiB
Raw Blame History

Prod-Deploy via vorgebaute Images (Plan B) — Runbook

Warum: Der direkte Build auf dem Prod-Coolify läuft in den Deployment-Timeout (~1 h; Ursache ist Coolifys Build-Pfad — u. a. die ~265-ARG-Injektion, die den Layer-Cache bei jedem Deploy bricht → Kaltbau). Lösung: Images einmal auf einem leistungsfähigen Host bauen, in die Registry pushen, und der Prod-Host zieht nur. Ergebnis: Prod-Deploy = Pull + Migrate = Minuten statt Stunde.

Topologie (Stand 2026-09-10)

Rolle Host
Build-Host (baut + pusht) 192.168.1.155 — lokales Coolify (= local-gitea-Host), amd64, Docker
Registry git.certvia.de (Gitea Container Registry), Namespace msolarczek
Prod (certvia_prod, GEFIM live) coolify.certvia.de (eigener Server, ≠ 192.168)
Quelle git.certvia.de/msolarczek/certvia, Branch main

Beteiligte Dateien im Repo:

  • docker-compose.coolify.prebuilt.yml — wie docker-compose.coolify.yml, aber die App-Services ziehen ${REGISTRY:-git.certvia.de/msolarczek}/certvia-*:${IMAGE_TAG:-main} statt zu bauen (postgres/redis unverändert).
  • scripts/build-and-push-images.sh — baut + pusht die drei Images.

Service → Image (Dockerfile-Target):

  • app → certvia-app (runner)
  • migrate, worker, backup-worker, incident-inbound-worker, garage-provision → certvia-migrate (migrate)
  • garage → certvia-garage (garage)

Voraussetzung: Gitea-Token

Token in git.certvia.de → Settings → Applications mit Scopes: read:repository (Klonen) + read:package + write:package (Image Push/Pull).

Ablauf je Release

1. Auf dem Build-Host (192.168.1.155)

docker login git.certvia.de -u msolarczek          # Passwort = Token
git clone https://msolarczek:<TOKEN>@git.certvia.de/msolarczek/certvia.git cv-build   # oder: cd cv-build && git fetch && git pull
cd cv-build && git checkout main && git pull
ALSO_MAIN=true ./scripts/build-and-push-images.sh   # baut+pusht Tag <SHA> UND :main

Wichtig: ALSO_MAIN=true setzen → es wird zusätzlich das bewegliche Tag :main gepusht. Coolify zieht per Default :main (siehe Gotcha IMAGE_TAG unten).

2. Prod-Host (coolify.certvia.de) einmalig am Registry anmelden

docker login git.certvia.de -u msolarczek           # Passwort = Token

(oder in der Coolify-UI unter Settings → Docker Registries hinterlegen). Nur beim ersten Mal / nach Token-Wechsel nötig.

3. Coolify (certvia_prod, coolify.certvia.de)

  • Configuration → „Docker Compose Location" = docker-compose.coolify.prebuilt.yml (einmalig).
  • Env unverändert: RUN_DEMO_SEED=false, BOOTSTRAP_ADMIN=false.
  • Redeploy. Log zeigt Pull der certvia-*:main → migrate (achte auf neue Migration) → garage/garage-provision → app healthy.

4. Nach dem Deploy — Bestandsmandanten-Migrationen der Fachdaten

Nur nötig, wenn eine Änderung Bestandsmandanten betrifft (z. B. der 5×5-Backfill). In Coolify → certvia_prod → Service backup-worker/worker → Terminal (oder per SSH docker exec):

npx tsx scripts/backfill-risk-5x5.ts        # idempotent, alle Mandanten

5. Smoke-Test

Login → betroffene Modulseiten prüfen (z. B. /processes, /dependencies).

Gotchas (aus dem ersten Live-Lauf gelernt)

  • IMAGE_TAG wird von Coolify NICHT in die Compose-Interpolation gereicht → die Datei fällt auf :main zurück. Deshalb :main immer mitpushen (ALSO_MAIN=true). SHA-genaues Pinning müsste erst geklärt werden (dann IMAGE_TAG=<sha> in Coolify-Env).
  • Coolify entfernt die alten Container VOR dem Pull. Fehlt der Ziel-Tag in der Registry, schlägt der Pull fehl und prod ist unten. Also immer erst Images (inkl. :main) pushen, dann Redeploy.
  • Klon-403: Ein reiner Package-Token darf nicht klonen — read:repository fehlt.
  • Migration-Drift ungefährlich: prisma migrate deploy läuft auch dann sauber (Exit 0), wenn die DB eine angewandte Migration hat, die lokal nicht mehr existiert (empirisch geprüft).
  • Nach Nutzung Token, der im Klartext (URL/History) auftauchte, widerrufen.

Rollback

Alten Stand deployen: früheres Image-Tag als :main retaggen+pushen (auf dem Build-Host) und Redeploy — oder Compose-Location zurück auf docker-compose.coolify.yml (Host-Build, langsam) als Notnagel.