# worker-Rolle: Event-Dispatcher, Kalender-Outbox und Webhook-Zustellung # (Spec 2026-10-12 Abschnitt 2). Kein Service und kein Ingress; Port 3002 # beantwortet nur /health fuer die Probes. Alle Schleifen arbeiten mit # SKIP LOCKED, mehr als ein Replica waere also moeglich. apiVersion: apps/v1 kind: Deployment metadata: name: apicore-worker labels: app: apicore-worker spec: replicas: 1 # Wie bei der api: scheitert die Migration, laeuft der alte Worker weiter. strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: apicore-worker template: metadata: labels: app: apicore-worker db-client: "true" spec: automountServiceAccountToken: false terminationGracePeriodSeconds: 30 securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 seccompProfile: type: RuntimeDefault volumes: - name: tmp emptyDir: {} initContainers: # Ohne Seed: den fuehrt nur die api aus. - name: migrate image: git.encry.de/nick.rosenloecher/apicore-backend imagePullPolicy: IfNotPresent command: ["node", "node_modules/prisma/build/index.js", "migrate", "deploy"] env: - name: HOME value: /tmp - name: CHECKPOINT_DISABLE value: "1" envFrom: - configMapRef: name: apicore-backend-config - secretRef: name: apicore-backend-secret securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] volumeMounts: - name: tmp mountPath: /tmp resources: requests: cpu: 50m memory: 192Mi limits: cpu: 500m memory: 512Mi containers: - name: apicore-worker image: git.encry.de/nick.rosenloecher/apicore-backend imagePullPolicy: IfNotPresent command: ["node", "dist/worker.js"] env: - name: APICORE_ROLE value: worker - name: WORKER_HEALTH_PORT value: "3002" - name: HOME value: /tmp - name: TELEGRAM_BOT_TOKEN valueFrom: secretKeyRef: name: apicore-telegram key: TELEGRAM_BOT_TOKEN optional: true envFrom: - configMapRef: name: apicore-backend-config - secretRef: name: apicore-backend-secret ports: - name: health containerPort: 3002 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: ["ALL"] volumeMounts: - name: tmp mountPath: /tmp # /health ist gesund, wenn die DB in hoechstens 5 s antwortet und # der letzte Dispatcher-Durchlauf hoechstens 2 Minuten her ist. # Darum timeoutSeconds 5 statt der Vorgabe von 1 s. startupProbe: httpGet: path: /health port: health failureThreshold: 30 periodSeconds: 10 timeoutSeconds: 5 livenessProbe: httpGet: path: /health port: health periodSeconds: 30 failureThreshold: 3 timeoutSeconds: 5 readinessProbe: httpGet: path: /health port: health periodSeconds: 15 timeoutSeconds: 5 resources: requests: cpu: 20m memory: 128Mi limits: cpu: 200m memory: 256Mi