# ============================================================================= # AI Software Factory — Web (Next.js) Deployment + Service # # 2 replicas. The public ingress routes "/" here. # ============================================================================= apiVersion: apps/v1 kind: Deployment metadata: name: web labels: app.kubernetes.io/name: web app.kubernetes.io/component: frontend spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: web strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 1 template: metadata: labels: app.kubernetes.io/name: web annotations: checksum/config: "factory-config" spec: containers: - name: web image: ghcr.io/ai-software-factory/web:TAG imagePullPolicy: IfNotPresent ports: - containerPort: 3000 name: http envFrom: - configMapRef: name: factory-config env: - name: PORT value: "3000" - name: NEXT_PUBLIC_API_URL value: "https://factory.example.com/api" - name: NEXT_PUBLIC_REALTIME_URL value: "wss://factory.example.com/ws" resources: requests: cpu: 200m memory: 512Mi limits: cpu: "1" memory: 1Gi livenessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 30 periodSeconds: 20 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 securityContext: allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 seccompProfile: type: RuntimeDefault terminationGracePeriodSeconds: 30 --- apiVersion: v1 kind: Service metadata: name: web labels: app.kubernetes.io/name: web spec: type: ClusterIP selector: app.kubernetes.io/name: web ports: - name: http port: 3000 targetPort: 3000