apiVersion: apps/v1 kind: Deployment metadata: name: hosting-backend namespace: hosting labels: app: hosting-backend version: v1 spec: replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: hosting-backend template: metadata: labels: app: hosting-backend version: v1 annotations: prometheus.io/scrape: "false" spec: # Pod disruption budget for high availability securityContext: fsGroup: 33 runAsNonRoot: false serviceAccountName: hosting-backend # Init containers for database setup initContainers: - name: migrate image: gitea.vidoks.fr/sortifal/hosting-backend-prod:latest imagePullPolicy: IfNotPresent command: ["php", "artisan", "migrate", "--force"] env: - name: APP_ENV value: production - name: DB_CONNECTION value: mysql - name: DB_HOST valueFrom: secretKeyRef: name: database-credentials key: host - name: DB_PORT valueFrom: secretKeyRef: name: database-credentials key: port - name: DB_DATABASE valueFrom: secretKeyRef: name: database-credentials key: database - name: DB_USERNAME valueFrom: secretKeyRef: name: database-credentials key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: database-credentials key: password securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: false containers: - name: hosting-backend image: gitea.vidoks.fr/sortifal/hosting-backend-prod:latest imagePullPolicy: IfNotPresent # Ports ports: - name: http containerPort: 80 protocol: TCP # Environment variables env: - name: APP_ENV value: production - name: APP_DEBUG value: "false" - name: FRONTEND_URL value: https://portfolio-host.com - name: ANSIBLE_HOST_KEY_CHECKING value: "False" - name: DB_CONNECTION value: mysql - name: DB_HOST valueFrom: secretKeyRef: name: database-credentials key: host - name: DB_PORT valueFrom: secretKeyRef: name: database-credentials key: port - name: DB_DATABASE valueFrom: secretKeyRef: name: database-credentials key: database - name: DB_USERNAME valueFrom: secretKeyRef: name: database-credentials key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: database-credentials key: password # Volume mounts volumeMounts: - name: ssh-key mountPath: /root/.ssh readOnly: true # Resource limits resources: limits: cpu: 500m memory: 512Mi requests: cpu: 250m memory: 256Mi # Health checks livenessProbe: httpGet: path: /api/ping port: 80 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /api/ping port: 80 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 2 # Security context securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL readOnlyRootFilesystem: false # Affinity rules for pod distribution affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - hosting-backend topologyKey: kubernetes.io/hostname # Volumes volumes: - name: ssh-key secret: secretName: ansible-ssh-key defaultMode: 0400