140 lines
4.0 KiB
Markdown
140 lines
4.0 KiB
Markdown
# 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:<tag> .
|
|
```
|
|
|
|
`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:<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`:
|
|
|
|
```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 <registry>/<image>:<build-number> .`
|
|
9. `docker push <registry>/<image>:<build-number>`
|
|
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.
|