1# ============================================================================= 2# AI Software Factory — API (NestJS) Deployment + Service + HPA 3# 4# 2 replicas by default, autoscaled 2..10 on CPU. 5# The image tag is patched by kustomization.yaml (TAG variable). 6# ============================================================================= 7apiVersion: apps/v1 8kind: Deployment 9metadata: 10 name: api 11 labels: 12 app.kubernetes.io/name: api 13 app.kubernetes.io/component: backend 14spec: 15 replicas: 2 16 selector: 17 matchLabels: 18 app.kubernetes.io/name: api 19 strategy: 20 type: RollingUpdate 21 rollingUpdate: 22 maxUnavailable: 0 23 maxSurge: 1 24 template: 25 metadata: 26 labels: 27 app.kubernetes.io/name: api 28 annotations: 29 # Re-roll pods when the configmap changes (see kustomization patch). 30 checksum/config: "factory-config" 31 spec: 32 # If the registry requires auth, set an imagePullSecret here: 33 # imagePullSecrets: 34 # - name: ghcr-pull 35 containers: 36 - name: api 37 # Tag is substituted by kustomize (TAG variable). 38 image: ghcr.io/ai-software-factory/api:TAG 39 imagePullPolicy: IfNotPresent 40 ports: 41 - containerPort: 4000 42 name: http 43 envFrom: 44 - configMapRef: 45 name: factory-config 46 - secretRef: 47 name: factory-secrets 48 env: 49 - name: PORT 50 value: "4000" 51 resources: 52 requests: 53 cpu: 250m 54 memory: 512Mi 55 limits: 56 cpu: 1000m 57 memory: 1Gi 58 livenessProbe: 59 httpGet: 60 path: /api/v1/health 61 port: 4000 62 initialDelaySeconds: 30 63 periodSeconds: 15 64 timeoutSeconds: 5 65 failureThreshold: 3 66 readinessProbe: 67 httpGet: 68 path: /api/v1/health/ready 69 port: 4000 70 initialDelaySeconds: 10 71 periodSeconds: 10 72 timeoutSeconds: 3 73 failureThreshold: 3 74 securityContext: 75 allowPrivilegeEscalation: false 76 runAsNonRoot: true 77 # The image must include a non-root user; runAsUser below is a 78 # safe default for the official node base images (node = 1000). 79 runAsUser: 1000 80 runAsGroup: 1000 81 seccompProfile: 82 type: RuntimeDefault 83 terminationGracePeriodSeconds: 30 84--- 85apiVersion: v1 86kind: Service 87metadata: 88 name: api 89 labels: 90 app.kubernetes.io/name: api 91spec: 92 type: ClusterIP 93 selector: 94 app.kubernetes.io/name: api 95 ports: 96 - name: http 97 port: 4000 98 targetPort: 4000 99--- 100apiVersion: autoscaling/v2 101kind: HorizontalPodAutoscaler 102metadata: 103 name: api 104spec: 105 scaleTargetRef: 106 apiVersion: apps/v1 107 kind: Deployment 108 name: api 109 minReplicas: 2 110 maxReplicas: 10 111 behavior: 112 scaleUp: 113 stabilizationWindowSeconds: 60 114 policies: 115 - type: Pods 116 value: 2 117 periodSeconds: 60 118 scaleDown: 119 stabilizationWindowSeconds: 300 120 policies: 121 - type: Pods 122 value: 1 123 periodSeconds: 120 124 metrics: 125 - type: Resource 126 resource: 127 name: cpu 128 target: 129 type: Utilization 130 averageUtilization: 70 131