# Next.js frontend workload for the first production deployment: serves pages, # static assets, and SSR only. All /api, /uploads, and /generated-results # traffic is routed to zhinian-go-api by the Ingress, so this workload holds no # RDS credentials and needs only the shared session secret for local cookie # verification in the middleware. apiVersion: apps/v1 kind: Deployment metadata: name: zhinian-web namespace: zhinian spec: # Keep one replica until uploaded/generated files are stored in OSS or another # shared object store. PostgreSQL alone does not make local runtime files shared. replicas: 1 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app.kubernetes.io/name: zhinian app.kubernetes.io/component: web template: metadata: labels: app.kubernetes.io/name: zhinian app.kubernetes.io/component: web spec: automountServiceAccountToken: false securityContext: seccompProfile: type: RuntimeDefault containers: - name: web image: REGISTRY/PROJECT/zhinian-aigc:REPLACE_TAG imagePullPolicy: IfNotPresent ports: - name: http containerPort: 3000 envFrom: - configMapRef: name: zhinian-runtime env: # The session secret must be the same value the Go backend uses so # the frontend middleware and the Go backend verify the same cookies. - name: ZHINIAN_AUTH_SESSION_SECRET valueFrom: secretKeyRef: name: zhinian-web-auth key: ZHINIAN_AUTH_SESSION_SECRET startupProbe: httpGet: path: /api/health port: http periodSeconds: 5 failureThreshold: 24 readinessProbe: httpGet: path: /api/health port: http periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 livenessProbe: httpGet: path: /api/health port: http periodSeconds: 20 timeoutSeconds: 3 failureThreshold: 3 resources: requests: cpu: 250m memory: 512Mi limits: cpu: "1" memory: 1Gi securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] # The current image runs as root. Add a fixed non-root image user and # verify /app/.runtime permissions before enabling runAsNonRoot.