feat: Backend migriert die Datenbank beim Start selbst statt ueber Job
Kein separater Kubernetes-Job mehr. Dockerfile-CMD fuehrt jetzt `npm run migrate:deploy` aus, bevor `node dist/main.js` startet - Tabellen werden beim ersten Verbinden automatisch angelegt. Sicher bei mehreren gleichzeitig startenden Pod-Replicas (replicas: 2), da Prisma migrate deploy einen DB-seitigen Advisory-Lock nutzt. deployment.yaml bekommt eine startupProbe (failureThreshold 30 x periodSeconds 10 = bis zu 5 Min), damit liveness/readiness den Container waehrend der Migration nicht neu starten. ARCHITECTURE.md entsprechend aktualisiert, migrate-job.yaml entfernt.
This commit is contained in:
1 parent
a6e5b0331f
commit
76a9e9c3a4
4 files changed
+18
-31
No files matched your search
+1
-1
@@ -105,7 +105,7 @@ Fachliche Annahmen, getroffen weil das Lastenheft an der Stelle keine eindeutige
|
||||
|
||||
## 8. Backup & Restore
|
||||
|
||||
**Schema-Migrationen (Reproduzierbarkeit):** Ausschließlich `prisma/migrations/` als Quelle der Wahrheit. Lokal/Entwicklung: `npx prisma migrate dev`. Gegen jede Produktions- oder Staging-Datenbank ausschließlich `npx prisma migrate deploy` (idempotent, wendet nur fehlende Migrationen an, kein Schema-Drift). `prisma db push` wird an keiner Stelle im Code, in Skripten oder im Dockerfile verwendet und ist für Produktions-/Staging-Umgebungen untersagt. `migrate deploy` läuft als eigener Schritt vor dem Rollout, nicht im `CMD` des Runtime-Images, damit mehrere Pod-Replicas nicht gleichzeitig Migrationen ausführen: `deploy/k8s/backend/migrate-job.yaml` ist ein Kubernetes-`Job`, der dasselbe Backend-Image mit überschriebenem `command` (`npm run migrate:deploy`) nutzt – kein separates Migrations-Image. Reihenfolge und `kubectl`-Befehle stehen als Kommentar in der Datei.
|
||||
**Schema-Migrationen (Reproduzierbarkeit):** Ausschließlich `prisma/migrations/` als Quelle der Wahrheit. Lokal/Entwicklung: `npx prisma migrate dev`. Gegen jede Produktions- oder Staging-Datenbank ausschließlich `npx prisma migrate deploy` (idempotent, wendet nur fehlende Migrationen an, kein Schema-Drift). `prisma db push` wird an keiner Stelle im Code, in Skripten oder im Dockerfile verwendet und ist für Produktions-/Staging-Umgebungen untersagt. Der Backend-Container führt `migrate deploy` selbst beim Start aus, bevor der Server Verbindungen annimmt (Dockerfile-`CMD`: `npm run migrate:deploy && node dist/main.js`) – kein separater Kubernetes-`Job`. Bei `replicas: 2` starten mehrere Pods potenziell gleichzeitig; das ist unproblematisch, da Prisma für `migrate deploy` einen datenbankseitigen Advisory-Lock nutzt – eine Instanz wendet die Migrationen an, die anderen warten kurz und finden danach nichts mehr zu tun. `deploy/k8s/backend/deployment.yaml` hat dafür eine `startupProbe` mit großzügigem `failureThreshold`, damit liveness/readiness den Container nicht neu starten, während die (beim allerersten Deploy ggf. länger laufende) Migration noch durchläuft.
|
||||
|
||||
**Datensicherung:** Seit der Entscheidung, PostgreSQL selbst im Cluster zu betreiben (siehe CLAUDE.md), liegt die Backup-Verantwortung bei diesem Projekt, nicht mehr bei einem externen Cluster-/DBA-Betrieb. Aktuell **noch nicht umgesetzt** (offener Punkt, siehe TASKS.md) – empfohlene Strategie:
|
||||
|
||||
|
||||
@@ -16,11 +16,14 @@ RUN npm ci --omit=dev
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY --from=builder /app/generated ./generated
|
||||
# schema.prisma, migrations/ und prisma.config.ts: noetig fuer
|
||||
# `npm run migrate:deploy` (siehe deploy/k8s/backend/migrate-job.yaml), das
|
||||
# dasselbe Image mit ueberschriebenem command nutzt statt eines eigenen
|
||||
# Migrations-Images.
|
||||
# `npm run migrate:deploy`, das der Container beim Start selbst ausfuehrt
|
||||
# (siehe CMD unten), bevor der Server Verbindungen annimmt.
|
||||
COPY --from=builder /app/prisma ./prisma
|
||||
COPY --from=builder /app/prisma.config.ts ./prisma.config.ts
|
||||
EXPOSE 3001
|
||||
USER node
|
||||
CMD ["node", "dist/main.js"]
|
||||
# migrate deploy ist idempotent und nutzt einen DB-seitigen Advisory-Lock,
|
||||
# daher unproblematisch bei mehreren gleichzeitig startenden Pod-Replicas:
|
||||
# eine Instanz wendet die Migrationen an, die anderen warten kurz und finden
|
||||
# danach nichts mehr zu tun.
|
||||
CMD ["sh", "-c", "npm run migrate:deploy && node dist/main.js"]
|
||||
@@ -24,6 +24,16 @@ spec:
|
||||
name: apicore-backend-config
|
||||
- secretRef:
|
||||
name: apicore-backend-secret
|
||||
# Container fuehrt beim Start selbst `prisma migrate deploy` aus,
|
||||
# bevor der Server Verbindungen annimmt (siehe Dockerfile CMD) -
|
||||
# startupProbe gibt dafuer bis zu 5 Minuten Zeit, ohne dass
|
||||
# liveness/readiness in der Zwischenzeit einen Neustart ausloesen.
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health/ready
|
||||
port: 3001
|
||||
failureThreshold: 30
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
# Job statt Teil des Deployment-CMD: laeuft einmalig vor dem Rollout, damit
|
||||
# nicht mehrere Backend-Pod-Replicas gleichzeitig Migrationen ausfuehren
|
||||
# (siehe ARCHITECTURE.md Abschnitt 8). Jobs sind unveraenderlich, daher vor
|
||||
# jedem Deploy mit neuem Image-Tag zuerst loeschen:
|
||||
#
|
||||
# kubectl delete job apicore-backend-migrate --ignore-not-found
|
||||
# kubectl apply -f deploy/k8s/backend/migrate-job.yaml
|
||||
# kubectl wait --for=condition=complete job/apicore-backend-migrate --timeout=120s
|
||||
# kubectl apply -f deploy/k8s/backend/deployment.yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: apicore-backend-migrate
|
||||
spec:
|
||||
backoffLimit: 2
|
||||
ttlSecondsAfterFinished: 3600
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: migrate
|
||||
image: git.encry.de/nick.rosenloecher/apicore-backend:latest
|
||||
command: ["npm", "run", "migrate:deploy"]
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: apicore-backend-secret
|
||||
Reference in new issue
Block a user