xpeditis2.0/infra/prod/k8s/base/05-frontend.yaml
2026-09-07 21:40:50 +02:00

164 lines
4.5 KiB
YAML

# =============================================================================
# Frontend Next.js 14 (sortie standalone)
# =============================================================================
# RAPPEL CRITIQUE : NEXT_PUBLIC_API_URL est fige au moment du BUILD de l'image
# (next.config.js, bloc `env`). Une image construite pour la preprod pointera
# toujours vers api.preprod.xpeditis.com, quelles que soient les variables
# injectees ici. L'image du frontend doit donc etre RECONSTRUITE pour la prod,
# jamais promue depuis la preprod. Le workflow cd-main.yml applique cette regle.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: xpeditis-frontend
namespace: xpeditis-prod
labels:
app.kubernetes.io/name: xpeditis-frontend
app.kubernetes.io/component: web
app.kubernetes.io/part-of: xpeditis
spec:
replicas: 2
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: xpeditis-frontend
template:
metadata:
labels:
app.kubernetes.io/name: xpeditis-frontend
app.kubernetes.io/component: web
app.kubernetes.io/part-of: xpeditis
spec:
imagePullSecrets:
- name: regcred
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: xpeditis-frontend
securityContext:
runAsNonRoot: true
runAsUser: 1001
runAsGroup: 1001
fsGroup: 1001
seccompProfile:
type: RuntimeDefault
terminationGracePeriodSeconds: 30
containers:
- name: frontend
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:latest
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 3000
protocol: TCP
env:
- name: NODE_ENV
value: "production"
- name: PORT
value: "3000"
- name: HOSTNAME
value: "0.0.0.0"
# Lues cote serveur uniquement (route handlers, server actions).
# Le code client, lui, a deja la valeur figee au build.
- name: NEXT_PUBLIC_API_URL
value: "https://api.xpeditis.com"
- name: NEXT_PUBLIC_APP_URL
value: "https://app.xpeditis.com"
- name: NEXT_TELEMETRY_DISABLED
value: "1"
startupProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 5
periodSeconds: 3
failureThreshold: 30
livenessProbe:
httpGet:
path: /api/health
port: http
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /api/health
port: http
initialDelaySeconds: 3
periodSeconds: 10
timeoutSeconds: 3
resources:
requests:
cpu: 200m
memory: 384Mi
limits:
cpu: 1000m
memory: 1Gi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
# Le build standalone n'ecrit qu'en cache : on peut donc verrouiller
# la racine et n'ouvrir que les deux repertoires necessaires.
readOnlyRootFilesystem: true
volumeMounts:
- name: next-cache
mountPath: /app/.next/cache
- name: tmp
mountPath: /tmp
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"]
volumes:
- name: next-cache
emptyDir:
sizeLimit: 512Mi
- name: tmp
emptyDir:
sizeLimit: 128Mi
---
apiVersion: v1
kind: Service
metadata:
name: xpeditis-frontend
namespace: xpeditis-prod
labels:
app.kubernetes.io/name: xpeditis-frontend
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: xpeditis-frontend
ports:
- name: http
port: 3000
targetPort: http
protocol: TCP
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: xpeditis-frontend
namespace: xpeditis-prod
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: xpeditis-frontend