Files
Artista-Filmcamp/k8s/base/jobs.yaml
T
Nick SzaunigandClaude Opus 5.5 95e3733ab8
Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 2m19s
refactor: Kubernetes-Ressourcen und Images heissen artista-modelcamp
Alle Ressourcen tragen den Praefix artista-modelcamp- im Namespace
artista; Images <owner>/artista-modelcamp und
<owner>/artista-modelcamp-tools. DATABASE_URL-Host, Backup-Host,
Traefik-Middleware-Referenz und Betriebsdoku entsprechend angepasst.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-27 14:38:37 +02:00

160 lines
5.4 KiB
YAML

# --- Migration ----------------------------------------------------------------
# Als SUSPENDIERTER CronJob definiert, damit Kustomize das Image mit der
# App gleichzieht. Er laeuft nie von selbst, sondern bewusst vor jedem
# Rollout:
# kubectl -n artista create job migrate-$(date +%Y%m%d%H%M) --from=cronjob/artista-modelcamp-migrate
# kubectl -n artista wait --for=condition=complete job/migrate-… --timeout=5m
apiVersion: batch/v1
kind: CronJob
metadata:
name: artista-modelcamp-migrate
spec:
suspend: true
schedule: "0 0 1 1 *"
jobTemplate:
spec:
backoffLimit: 0
ttlSecondsAfterFinished: 86400
template:
metadata:
labels:
artista/db-client: "true"
spec:
restartPolicy: Never
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 1001
seccompProfile: { type: RuntimeDefault }
containers:
- name: migrate
image: artista-modelcamp-tools
command: ["prisma", "migrate", "deploy"]
envFrom:
- secretRef: { name: artista-modelcamp-secrets }
resources:
requests: { cpu: 50m, memory: 128Mi }
limits: { memory: 512Mi }
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: ["ALL"] }
---
# --- Worker -------------------------------------------------------------------
# Gibt abgelaufene Reservierungen frei (nach Rueckfrage bei Stripe), zieht
# faellige Raten ein, trennt Zahlungsmethoden nach der letzten Rate,
# versendet den E-Mail-Ausgang. Idempotent; Forbid verhindert
# ueberlappende Laeufe zusaetzlich.
apiVersion: batch/v1
kind: CronJob
metadata:
name: artista-modelcamp-worker
spec:
schedule: "*/10 * * * *"
timeZone: "Europe/Berlin"
concurrencyPolicy: Forbid
startingDeadlineSeconds: 300
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
backoffLimit: 1
activeDeadlineSeconds: 900
template:
metadata:
labels:
artista/db-client: "true"
spec:
restartPolicy: Never
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 1001
seccompProfile: { type: RuntimeDefault }
containers:
- name: worker
image: artista-modelcamp-tools
command: ["tsx", "scripts/worker.ts"]
envFrom:
- configMapRef: { name: artista-modelcamp-config }
- secretRef: { name: artista-modelcamp-secrets }
resources:
requests: { cpu: 50m, memory: 192Mi }
limits: { memory: 512Mi }
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: ["ALL"] }
---
# --- Sicherung ----------------------------------------------------------------
# Taeglicher pg_dump mit 30 Tagen Aufbewahrung. Das Backup-Volume darf ein
# Netzwerkspeicher (NFS/SMB) sein. Zusaetzlich regelmaessig aus dem Cluster
# kopieren (docs/BETRIEB.md, "Sicherung und Wiederherstellung").
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: artista-modelcamp-db-backup
spec:
accessModes: ["ReadWriteOnce"]
# storageClassName: smb-backup
resources:
requests:
storage: 10Gi
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: artista-modelcamp-db-backup
spec:
schedule: "15 3 * * *"
timeZone: "Europe/Berlin"
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 5
jobTemplate:
spec:
backoffLimit: 2
template:
metadata:
labels:
artista/db-client: "true"
spec:
restartPolicy: OnFailure
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 70
runAsGroup: 70
fsGroup: 70
seccompProfile: { type: RuntimeDefault }
containers:
- name: pg-dump
# Gleiche Hauptversion wie der Server.
image: postgres:18.1-alpine
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef: { name: artista-modelcamp-secrets, key: DB_PASSWORD }
command: ["/bin/sh", "-c"]
args:
- |
set -eu
set -o pipefail
target="/backup/artista-$(date -u +%Y-%m-%d_%H%M).dump"
# Custom-Format: komprimiert, selektiv wiederherstellbar.
pg_dump --host=artista-modelcamp-postgres --username=artista --dbname=artista \
--format=custom --file="${target}.partial"
mv "${target}.partial" "${target}"
find /backup -name 'artista-*.dump.partial' -mtime +1 -delete
find /backup -name 'artista-*.dump' -mtime +30 -delete
ls -lh /backup
resources:
requests: { cpu: 50m, memory: 128Mi }
limits: { memory: 256Mi }
securityContext:
allowPrivilegeEscalation: false
capabilities: { drop: ["ALL"] }
volumeMounts:
- name: backup
mountPath: /backup
volumes:
- name: backup
persistentVolumeClaim: { claimName: artista-modelcamp-db-backup }