1# ============================================================================= 2# AI Software Factory — Web (Next.js) Deployment + Service 3# 4# 2 replicas. The public ingress routes "/" here. 5# ============================================================================= 6apiVersion: apps/v1 7kind: Deployment 8metadata: 9 name: web 10 labels: 11 app.kubernetes.io/name: web 12 app.kubernetes.io/component: frontend 13spec: 14 replicas: 2 15 selector: 16 matchLabels: 17 app.kubernetes.io/name: web 18 strategy: 19 type: RollingUpdate 20 rollingUpdate: 21 maxUnavailable: 0 22 maxSurge: 1 23 template: 24 metadata: 25 labels: 26 app.kubernetes.io/name: web 27 annotations: 28 checksum/config: "factory-config" 29 spec: 30 containers: 31 - name: web 32 image: ghcr.io/ai-software-factory/web:TAG 33 imagePullPolicy: IfNotPresent 34 ports: 35 - containerPort: 3000 36 name: http 37 envFrom: 38 - configMapRef: 39 name: factory-config 40 env: 41 - name: PORT 42 value: "3000" 43 - name: NEXT_PUBLIC_API_URL 44 value: "https://factory.example.com/api" 45 - name: NEXT_PUBLIC_REALTIME_URL 46 value: "wss://factory.example.com/ws" 47 resources: 48 requests: 49 cpu: 200m 50 memory: 512Mi 51 limits: 52 cpu: "1" 53 memory: 1Gi 54 livenessProbe: 55 httpGet: 56 path: / 57 port: 3000 58 initialDelaySeconds: 30 59 periodSeconds: 20 60 timeoutSeconds: 5 61 failureThreshold: 3 62 readinessProbe: 63 httpGet: 64 path: / 65 port: 3000 66 initialDelaySeconds: 10 67 periodSeconds: 10 68 timeoutSeconds: 3 69 failureThreshold: 3 70 securityContext: 71 allowPrivilegeEscalation: false 72 runAsNonRoot: true 73 runAsUser: 1000 74 runAsGroup: 1000 75 seccompProfile: 76 type: RuntimeDefault 77 terminationGracePeriodSeconds: 30 78--- 79apiVersion: v1 80kind: Service 81metadata: 82 name: web 83 labels: 84 app.kubernetes.io/name: web 85spec: 86 type: ClusterIP 87 selector: 88 app.kubernetes.io/name: web 89 ports: 90 - name: http 91 port: 3000 92 targetPort: 3000 93