# Deployment und Betrieb Die Anwendung wird als ein Docker-Image ausgeliefert. Das Image enthaelt das gebaute NestJS-Backend und das gebaute Angular-Frontend. ## Release-Build Vor jedem Release: ```bash npm ci npm run lint npm run format:check npm run typecheck npm test npm run build docker build -t registry.example.com/business-app: . ``` `npm run build` fuehrt aus: 1. API-Client generieren 2. API-Client bauen 3. Backend bauen 4. Frontend bauen 5. Frontend nach `apps/backend/dist/public` kopieren Das Dockerfile baut erneut im Container und erzeugt anschliessend ein schlankes Runtime-Image mit Non-Root-User. ## Runtime-Konfiguration Konfiguration erfolgt ueber Umgebungsvariablen. Nutze `.env.example` nur als Vorlage. Production-Secrets gehoeren in Secret Management, CI/CD Variables oder eine geschuetzte Server-Konfiguration. Wichtige Produktionswerte: - `NODE_ENV=production` - `APP_BASE_URL=https://app.example.com` - `FRONTEND_BASE_URL=https://app.example.com` - `TRUST_PROXY=true`, wenn hinter Reverse Proxy - `DATABASE_SSL=true`, wenn die Datenbank TLS erzwingt - `SWAGGER_ENABLED=false`, ausser bewusst anders entschieden - starke Werte fuer `SESSION_SECRET`, `SESSION_ENCRYPTION_KEY`, `OIDC_CLIENT_SECRET` ## Migrationen Migrationen werden nicht beim App-Start ausgefuehrt. Fuehre sie vor dem neuen App-Container aus, mit demselben Image und derselben Konfiguration: ```bash docker run --rm --env-file .env registry.example.com/business-app: node apps/backend/dist/database/run-migrations.js ``` Danach den App-Container starten oder aktualisieren. Wenn Migrationen fehlen, schlaegt der App-Start fehl beziehungsweise `/health/ready` bleibt nicht bereit. ## Container starten Ein einfaches Compose-Beispiel liegt in `compose.yml`: ```bash docker compose up -d ``` Der Container: - laeuft als Non-Root-User - verwendet ein read-only Root Filesystem - nutzt `/tmp` als tmpfs - dropt Linux Capabilities - prueft `/health/ready` als Healthcheck Compose baut oder nutzt das Image `internal-business-app:latest`. Fuer echte Deployments sollte ein versioniertes Registry-Image verwendet werden. ## Reverse Proxy Nginx oder ein Load Balancer sollte TLS terminieren und alle Routen an den App-Container weiterleiten. Die Angular-Dateien werden nicht separat durch Nginx ausgeliefert. Ein Beispiel liegt in `docs/nginx-example.conf`. Wichtig: - WebSocket-Konfiguration ist fuer dieses Boilerplate nicht erforderlich. - `X-Forwarded-Proto` und `X-Forwarded-For` sollten gesetzt werden. - `APP_BASE_URL` muss zur externen HTTPS-URL passen. - Wenn `TRUST_PROXY=true` gesetzt ist, muss der Proxy vertrauenswuerdig sein. ## Healthchecks - `/health/live`: Prozess lebt. - `/health/ready`: Datenbank erreichbar, Migration-Check initialisiert und keine offenen Migrationen. Readiness ist der richtige Check fuer Rolling Deployments und Container Orchestrierung. ## TeamCity-Beispiel 1. Checkout 2. `npm ci` 3. `npm run lint` 4. `npm run format:check` 5. `npm run typecheck` 6. `npm test` 7. `npm run build` 8. `docker build -t /: .` 9. `docker push /:` 10. Migration-Job mit neuem Image ausfuehren 11. App-Service auf neues Image aktualisieren 12. `/health/ready` pruefen ## Rollback Ein Rollback ist nur dann einfach, wenn die Datenbankmigrationen rueckwaerts kompatibel geplant wurden. Fuer riskante Schema-Aenderungen sollte das Expand- Contract-Muster verwendet werden: 1. Neue Spalten oder Tabellen hinzufuegen, alte weiter bedienen. 2. Anwendung umstellen. 3. Daten migrieren. 4. Alte Spalten oder Pfade in einem spaeteren Release entfernen. ## Betrieb Beobachte mindestens: - HTTP-Fehlerraten und Latenzen - Healthcheck-Status - Datenbankverbindungen - Login-Fehler vom OIDC Provider - `MIGRATION_MISSING` - Rate-Limit-Treffer, insbesondere `RATE_LIMIT_EXCEEDED` auf Login- und Admin-Endpunkten - Audit-Log fuer administrative Aktionen Logs sollten zentral gesammelt werden. Request IDs helfen dabei, Frontend-Fehler, Backend-Logs und Audit-Eintraege zusammenzufuehren.