4.0 KiB
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:
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:<tag> .
npm run build fuehrt aus:
- API-Client generieren
- API-Client bauen
- Backend bauen
- Frontend bauen
- Frontend nach
apps/backend/dist/publickopieren
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=productionAPP_BASE_URL=https://app.example.comFRONTEND_BASE_URL=https://app.example.comTRUST_PROXY=true, wenn hinter Reverse ProxyDATABASE_SSL=true, wenn die Datenbank TLS erzwingtSWAGGER_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:
docker run --rm --env-file .env registry.example.com/business-app:<tag> 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:
docker compose up -d
Der Container:
- laeuft als Non-Root-User
- verwendet ein read-only Root Filesystem
- nutzt
/tmpals tmpfs - dropt Linux Capabilities
- prueft
/health/readyals 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-ProtoundX-Forwarded-Forsollten gesetzt werden.APP_BASE_URLmuss zur externen HTTPS-URL passen.- Wenn
TRUST_PROXY=truegesetzt 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
- Checkout
npm cinpm run lintnpm run format:checknpm run typechecknpm testnpm run builddocker build -t <registry>/<image>:<build-number> .docker push <registry>/<image>:<build-number>- Migration-Job mit neuem Image ausfuehren
- App-Service auf neues Image aktualisieren
/health/readypruefen
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:
- Neue Spalten oder Tabellen hinzufuegen, alte weiter bedienen.
- Anwendung umstellen.
- Daten migrieren.
- 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_EXCEEDEDauf 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.