docs/HANDOVER-DEVOPS.md: Runtime-Architektur (Next standalone + Postgres/pgvector/ Redis/MinIO/Mailhog), Umgebungsvariablen, Build/Start, kritische Migrations-/ Bootstrap-Strategie (Migrationen laufen nicht beim Container-Start; erster Superadmin fehlt), Persistenz/Backup, bekannte Lücken (worker-Script fehlt, MinIO- Env, Reverse-Proxy/TLS, Healthcheck), Test-vs-Prod-Unterschiede, Deploy-Checkliste. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7.5 KiB
DevOps-Übergabe — ISMS-Tool (Deployment Test → Produktiv)
Stand: 2026-07-20 · Branch
main· Commit081c000Zweck: Betrieb/Deployment. Gemeinsame Arbeit an Dockerfile, Einrichtung Testserver (remote), danach Produktivserver. Ergänzt:docs/HANDOVER-DEV.md(App-Architektur/Setup) unddocs/HANDOVER-PM.md(fachlicher Status).
1. Überblick der Runtime
Die App ist eine Next.js-16-Anwendung im Standalone-Modus (output: "standalone" in next.config, Start via node server.js), zustandslos horizontal skalierbar. Zustand liegt ausschließlich in den Backing-Services.
| Service | Image / Herkunft | Port | Zweck | Persistenz |
|---|---|---|---|---|
| app | Multi-Stage-Build (Dockerfile) |
3000 | Web-App (Next.js standalone) | zustandslos |
| postgres | pgvector/pgvector:pg16 |
5432 | Primärdatenbank (inkl. vector-Extension) |
Volume pgdata |
| redis | redis:7-alpine |
6379 | Cache/Queue (für späteren BullMQ-Worker) | Volume redisdata |
| minio | minio/minio:latest |
9000/9001 | Objektspeicher (noch ungenutzt; für kommenden Logo-/Datei-Upload) | Volume miniodata |
| mailhog | mailhog/mailhog (Profil dev) |
1025/8025 | SMTP-Fang für Entwicklung | — |
| worker | s. Dockerfile (Profil worker) |
— | noch nicht lauffähig (kein worker-npm-Script vorhanden) |
— |
Alles bereits als docker-compose.yml im Repo-Root beschrieben; Dockerfile ist ein sauberer 3-Stage-Build (deps → builder mit prisma generate + next build → schlanker runner als non-root app-User).
2. Umgebungsvariablen (.env)
Vorlage: .env.example. Vollständige Liste:
| Variable | Zweck | Prod-Hinweis |
|---|---|---|
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB |
Compose-Init von Postgres | Secret (Passwort) |
DATABASE_URL |
Prisma-Verbindungsstring | Secret; muss auf denselben DB-Nutzer/-Namen zeigen |
REDIS_URL |
Redis-Verbindung | — |
AUTH_SECRET |
NextAuth-Signaturschlüssel (JWT) | Secret, zwingend gesetzt & stark |
AUTH_URL |
Öffentliche Basis-URL der App | pro Umgebung (Test/Prod) unterschiedlich, inkl. https:// |
AI_PROVIDER / AI_API_KEY |
KI-Chat / KI-Formulierungshilfe (noch ungenutzt) | Secret, optional |
SMTP_HOST/PORT/USER/PASSWORD/FROM |
E-Mail (noch ungenutzt; Einladungs-/Benachrichtigungsflow offen) | Secret, optional |
MINIO_ROOT_USER / MINIO_ROOT_PASSWORD |
Objektspeicher | fehlen in .env.example → für Prod ergänzen (sonst Compose-Defaults isms/isms-secret) |
Secrets gehören nicht ins Git. Für Prod: Secret-Management (Docker Secrets / Env aus Vault / CI-Variablen).
.env.exampleenthält nur Namen/Defaults.
3. Build & Start
# Image bauen
docker compose build app
# Test/lokal hochfahren (ohne dev-only mailhog)
docker compose up -d postgres redis minio app
# mit Mailhog (Dev): docker compose --profile dev up -d
# Worker (aktuell NICHT lauffähig, s. §6): docker compose --profile worker up -d worker
App danach unter AUTH_URL (Port 3000) erreichbar.
4. ⚠️ Datenbank-Migrationen & Bootstrap (kritisch)
Der App-Container führt KEINE Migrationen beim Start aus (CMD ist node server.js). Migrationen und das erste Provisioning sind ein separater Deploy-Schritt:
- Migrationen anwenden:
npx prisma migrate deploygegen die Ziel-DB.- Die
runner-Stage enthält Prisma-CLI/tsxnicht (nur Runtime-Trace). Migrationen daher aus derbuilder-Stage (vollernode_modules) oder aus einem eigenen Migrations-Job/CI-Step fahren. → Designentscheidung mit DevOps (z. B. Init-Containercommand: npx prisma migrate deploymit builder-Image,restart: "no"). - Die Init-Migration legt
CREATE EXTENSION IF NOT EXISTS "vector"an (pgvector) — das Postgres-Image bringt die Extension mit.
- Die
- Erster Mandant / Superadmin (Prod): Der Demo-Seed (
prisma/seed.ts) ist nur für Entwicklung (Demo-Mandant + Testnutzer) — nicht in Produktion ausführen. In Prod erfolgt das Anlegen von Kunden über die Admin-Konsole (provisionTenant). Offen: Es gibt aktuell kein Bootstrap-Skript für den allerersten Plattform-Admin — dieser muss initial angelegt werden (Skript/One-Off gegenprovisionTenantmitisPlatformAdmin: true, oder manuell). → Mit App-Entwickler abstimmen (kleiner Task).
5. Persistenz, Backup & Restore
- Volumes:
pgdata(kritisch),miniodata(künftig Uploads),redisdata(unkritisch, Cache). - Backups Prod: regelmäßiger
pg_dump(logisch) oder Volume-/Snapshot-Backup; MinIO-Bucket-Backup, sobald Uploads aktiv. Aufbewahrung + Restore-Test einplanen (DSGVO-Löschkonzept ist app-seitig noch offen). - Mandantentrennung ist logisch (eine DB,
tenant_id+ Postgres-RLS + App-Guard) — Backups umfassen alle Mandanten gemeinsam.
6. Bekannte Lücken / To-dos für DevOps
worker-Service nicht lauffähig: Es existiert keinnpm run worker-Script (BullMQ-Scheduler ist app-seitig noch nicht implementiert). Profilworkerbis dahin nicht starten.- Migrations-/Bootstrap-Strategie festlegen (§4) — Migrations-Job + Erst-Superadmin.
- MinIO-Env in
.envfür Prod ergänzen; MinIO wird erst mit dem kommenden Logo-/Datei-Upload wirklich genutzt (Bucket-Präfix je Mandant vorgesehen). - Reverse-Proxy + TLS vor der App (Port 3000 nicht direkt exponieren): Traefik/Caddy/nginx mit HTTPS;
AUTH_URLauf die öffentlichehttps://-Adresse setzen. Rate-Limiting/IP-Härtung für Login/Admin einplanen. - Ressourcen/Skalierung:
appist zustandslos → mehrere Replicas möglich; Sticky-Sessions nicht nötig (JWT). Postgres/Redis als Singleton bzw. Managed-Service. - Health/Observability: Postgres-Healthcheck vorhanden; für
appeinen HTTP-Healthcheck/Readiness ergänzen (derzeit keiner definiert). Log-Aggregation + Alerting einrichten. AUTH_SECRETje Umgebung eindeutig & stark; bei Rotation invalidieren alle Sessions.
7. Test- vs. Produktivumgebung — Unterschiede
| Aspekt | Test (Remote) | Produktiv |
|---|---|---|
| Daten | ggf. Demo-Seed erlaubt | kein Demo-Seed; nur echtes Provisioning |
| Secrets | Test-Werte | echte Secrets aus Secret-Store |
Mailhog (Profil dev) |
echtes SMTP-Relay | |
| TLS | optional/self-signed | verpflichtend, gültiges Zertifikat |
| Backups | optional | verpflichtend + Restore-Test |
| Skalierung | 1 Replica | ≥ 2 App-Replicas hinter Proxy |
8. Deploy-Checkliste (Kurz)
Testserver:
- Repo klonen/pullen (Gitea, Branch
main). .envaus.env.examplemit Test-Werten (inkl.MINIO_*).docker compose build app.docker compose up -d postgres redis minio.- Migrationen:
prisma migrate deploy(builder-Image/Job). - Erst-Superadmin anlegen (One-Off, s. §4) — für Test ggf. Demo-Seed ok.
docker compose up -d app; Reverse-Proxy/TLS davor; Smoke-Test (Login, Admin-Konsole, Modul-Seite).
Produktivserver: wie oben, aber Secret-Store, kein Demo-Seed, TLS verpflichtend, Backups + Monitoring aktiv, ≥ 2 App-Replicas, Migrations-/Bootstrap-Schritt in die Deploy-Pipeline integriert.
9. Referenzen im Repo
Dockerfile, docker-compose.yml, .env.example, next.config.* (output: standalone), prisma/schema.prisma + prisma/migrations/** (inkl. RLS-Policies & pgvector), prisma/seed.ts (nur Dev), src/server/provision.ts (Provisioning-Logik für Prod-Onboarding).