# The API, as a blue-green Rollout. # # Same shape as a Deployment, but the new version comes up alongside the old, # gets checked against Prometheus, and only then takes over the active Service. apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: nereus-api labels: app.kubernetes.io/name: nereus-api app.kubernetes.io/part-of: nereus spec: replicas: 2 revisionHistoryLimit: 3 selector: matchLabels: app.kubernetes.io/name: nereus-api template: metadata: labels: app.kubernetes.io/name: nereus-api app.kubernetes.io/part-of: nereus spec: imagePullSecrets: - name: nereus-registry securityContext: # distroless nonroot. runAsUser: 65532 runAsGroup: 65532 runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - name: api image: nereus-api:0.1.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 envFrom: - configMapRef: name: nereus-api-config env: - name: DATABASE_URL valueFrom: secretKeyRef: name: nereus-db key: DATABASE_URL # /healthz ignores Postgres, so a database outage makes pods unready # without restarting them. livenessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 3 periodSeconds: 10 timeoutSeconds: 2 failureThreshold: 3 # /readyz waits for migrations. readinessProbe: httpGet: path: /readyz port: http initialDelaySeconds: 3 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3 securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] readOnlyRootFilesystem: true volumeMounts: - name: tmp mountPath: /tmp resources: requests: cpu: 50m memory: 64Mi limits: memory: 256Mi volumes: - name: tmp emptyDir: medium: Memory sizeLimit: 16Mi strategy: blueGreen: activeService: nereus-api-active previewService: nereus-api-preview # Auto-promote only if the analysis passes; a failure aborts instead. autoPromotionEnabled: true # Keep the old ReplicaSet warm so an abort falls straight back. scaleDownDelaySeconds: 30 prePromotionAnalysis: templates: - templateName: nereus-api-error-rate args: - name: service value: nereus-api-preview