--- # Role: smartapp # Template: smartapp-web.yml.j2 # Déploiement du frontend web SmartApp (nginx) # Variables: # {{ smartapp_namespace }} - Namespace Kubernetes (défaut: smartapp) # {{ smartapp_domain }} - Domaine public (défaut: smartapp.digitribe.fr) --- apiVersion: v1 kind: Namespace metadata: name: {{ smartapp_namespace | default('smartapp') }} labels: app: smartapp component: web version: "1.0" --- apiVersion: apps/v1 kind: Deployment metadata: name: smartapp-web namespace: {{ smartapp_namespace | default('smartapp') }} labels: app: smartapp component: web version: "1.0" spec: replicas: 2 selector: matchLabels: app: smartapp component: web strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: labels: app: smartapp component: web version: "1.0" spec: containers: - name: nginx image: nginx:1.25-alpine imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 protocol: TCP resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "256Mi" livenessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 10 periodSeconds: 15 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 volumeMounts: - name: nginx-config mountPath: /etc/nginx/conf.d readOnly: true - name: static-content mountPath: /usr/share/nginx/html readOnly: true volumes: - name: nginx-config configMap: name: smartapp-web-nginx-config - name: static-content configMap: name: smartapp-web-static affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - smartapp - key: component operator: In values: - web topologyKey: kubernetes.io/hostname --- apiVersion: v1 kind: ConfigMap metadata: name: smartapp-web-nginx-config namespace: {{ smartapp_namespace | default('smartapp') }} labels: app: smartapp component: web version: "1.0" data: default.conf: | server { listen 80; server_name {{ smartapp_domain | default('smartapp.digitribe.fr') }}; root /usr/share/nginx/html; index index.html; # Health check endpoint location /healthz { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } # Static assets with caching location /static/ { expires 30d; add_header Cache-Control "public, immutable"; } # SPA fallback location / { try_files $uri $uri/ /index.html; } # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; } --- apiVersion: v1 kind: ConfigMap metadata: name: smartapp-web-static namespace: {{ smartapp_namespace | default('smartapp') }} labels: app: smartapp component: web version: "1.0" data: index.html: | SmartApp - DigiTribe

SmartApp - DigiTribe

Frontend web opérationnel.

--- apiVersion: v1 kind: Service metadata: name: smartapp-web namespace: {{ smartapp_namespace | default('smartapp') }} labels: app: smartapp component: web version: "1.0" spec: type: ClusterIP selector: app: smartapp component: web ports: - name: http port: 80 targetPort: 80 protocol: TCP --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: smartapp-web namespace: {{ smartapp_namespace | default('smartapp') }} labels: app: smartapp component: web version: "1.0" annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-body-size: "10m" cert-manager.io/cluster-issuer: "letsencrypt-prod" spec: ingressClassName: nginx tls: - hosts: - {{ smartapp_domain | default('smartapp.digitribe.fr') }} secretName: smartapp-web-tls rules: - host: {{ smartapp_domain | default('smartapp.digitribe.fr') }} http: paths: - path: / pathType: Prefix backend: service: name: smartapp-web port: number: 80