142 lines
4.2 KiB
YAML
142 lines
4.2 KiB
YAML
# AWOOOI Frontend (Next.js) Deployment
|
||
# 負責人: CIO
|
||
# 版本: v1.1
|
||
# 日期: 2026-03-20
|
||
# 更新: 2026-03-28 - 新增 startupProbe + revisionHistoryLimit:3 (Phase K0.5/K0.7)
|
||
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: awoooi-web
|
||
namespace: awoooi-prod
|
||
labels:
|
||
app: awoooi-web
|
||
system: awoooi
|
||
environment: prod
|
||
spec:
|
||
replicas: 2
|
||
revisionHistoryLimit: 3
|
||
selector:
|
||
matchLabels:
|
||
app: awoooi-web
|
||
environment: prod
|
||
system: awoooi
|
||
strategy:
|
||
type: RollingUpdate
|
||
rollingUpdate:
|
||
# 2026-06-13 Codex: no surge keeps topology spread honest during rollouts.
|
||
maxSurge: 0
|
||
maxUnavailable: 1
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: awoooi-web
|
||
system: awoooi
|
||
environment: prod
|
||
annotations:
|
||
awoooi.dev/topology-rebalance-generation: "2026-06-13T13:05:00+08:00"
|
||
spec:
|
||
# 2026-07-01 Codex: topology spread must not deadlock rollouts when the
|
||
# active prod placement has fewer eligible domains after reboot.
|
||
# Keep the skew preference, but allow scheduling so GitOps deploys can finish.
|
||
topologySpreadConstraints:
|
||
- maxSkew: 1
|
||
topologyKey: kubernetes.io/hostname
|
||
whenUnsatisfiable: ScheduleAnyway
|
||
labelSelector:
|
||
matchLabels:
|
||
app: awoooi-web
|
||
environment: prod
|
||
system: awoooi
|
||
containers:
|
||
- name: web
|
||
# 映像標籤由 CI/CD 動態注入 (格式: {sha}-{run_id})
|
||
# Harbor 金庫: 110 主機 (192.168.0.110:5000)
|
||
image: 192.168.0.110:5000/library/web:IMAGE_TAG_PLACEHOLDER
|
||
imagePullPolicy: Always
|
||
ports:
|
||
- containerPort: 3000
|
||
name: http
|
||
env:
|
||
- name: NODE_ENV
|
||
value: "production"
|
||
# 正式域名 (必須 https)
|
||
- name: NEXT_PUBLIC_API_URL
|
||
value: "https://awoooi.wooo.work"
|
||
# 2026-04-22 ogt: 移除前端硬碼 IP,改由 K8s 注入
|
||
- name: NEXT_PUBLIC_HOST_IPS
|
||
value: "192.168.0.110,192.168.0.112,192.168.0.120,192.168.0.188"
|
||
- name: NEXT_PUBLIC_K8S_VIP_INFO
|
||
value: "VIP 192.168.0.125 · kubectl :6443 · Web :32335 · API :32334"
|
||
- name: SENTRY_HOST
|
||
value: "http://192.168.0.110:9000"
|
||
envFrom:
|
||
- configMapRef:
|
||
name: awoooi-config
|
||
# 2026-03-28: 加入 Secret 參考 (Sentry DSN 等)
|
||
- secretRef:
|
||
name: awoooi-secrets
|
||
resources:
|
||
requests:
|
||
cpu: "100m"
|
||
memory: "256Mi"
|
||
limits:
|
||
cpu: "500m"
|
||
memory: "512Mi"
|
||
livenessProbe:
|
||
httpGet:
|
||
# 2026-05-31 Codex: probe a cheap API route instead of the
|
||
# localized app shell. The shell can block on SSR/middleware
|
||
# during rollout and caused transient 502 + liveness restarts.
|
||
path: /api/health
|
||
port: 3000
|
||
initialDelaySeconds: 30
|
||
periodSeconds: 10
|
||
timeoutSeconds: 5
|
||
failureThreshold: 3
|
||
readinessProbe:
|
||
httpGet:
|
||
path: /api/health
|
||
port: 3000
|
||
initialDelaySeconds: 5
|
||
periodSeconds: 5
|
||
timeoutSeconds: 3
|
||
failureThreshold: 3
|
||
# Phase K0.5: Startup Probe (允許最多 60 秒啟動時間)
|
||
startupProbe:
|
||
httpGet:
|
||
path: /api/health
|
||
port: 3000
|
||
initialDelaySeconds: 5
|
||
periodSeconds: 5
|
||
timeoutSeconds: 5
|
||
failureThreshold: 12
|
||
# 反親和性 - 分散到不同節點
|
||
affinity:
|
||
podAntiAffinity:
|
||
preferredDuringSchedulingIgnoredDuringExecution:
|
||
- weight: 100
|
||
podAffinityTerm:
|
||
labelSelector:
|
||
matchLabels:
|
||
app: awoooi-web
|
||
topologyKey: kubernetes.io/hostname
|
||
|
||
---
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: awoooi-web-svc
|
||
namespace: awoooi-prod
|
||
labels:
|
||
app: awoooi-web
|
||
spec:
|
||
type: NodePort
|
||
selector:
|
||
app: awoooi-web
|
||
ports:
|
||
- port: 3000
|
||
targetPort: 3000
|
||
nodePort: 32335
|
||
name: http
|