--- apiVersion: apps/v1 kind: Deployment metadata: name: towerops namespace: towerops spec: replicas: 3 # Run 3 replicas for high availability strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # Allow 1 extra pod during rollout maxUnavailable: 0 # Keep all pods running during rollout minReadySeconds: 30 # Wait 30s after pod is ready before considering it available selector: matchLabels: app: towerops template: metadata: labels: app: towerops spec: # Use system-cluster-critical priority to ensure towerops starts after CNI is ready priorityClassName: system-cluster-critical terminationGracePeriodSeconds: 90 # Allow 90s for graceful shutdown and connection draining imagePullSecrets: - name: gitlab-registry securityContext: runAsNonRoot: true runAsUser: 65534 fsGroup: 65534 seccompProfile: type: RuntimeDefault containers: - name: towerops image: registry.gitlab.com/towerops/towerops:latest imagePullPolicy: Always securityContext: allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: 65534 capabilities: drop: - ALL seccompProfile: type: RuntimeDefault ports: - containerPort: 4000 name: http - containerPort: 4369 name: epmd - containerPort: 9000 name: dist lifecycle: preStop: exec: command: - /bin/sh - -c - | # Stop accepting new connections by failing readiness probe # Give load balancer time to remove pod from rotation # Allow existing connections to complete sleep 20 env: - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: DEPLOY_TIMESTAMP value: "1970-01-01T00:00:00Z" # Placeholder, updated by GitLab CI on deploy - name: ETCD_ENABLED value: "true" - name: RELEASE_DISTRIBUTION value: "name" - name: RELEASE_NODE value: "towerops@$(POD_IP)" - name: PORT value: "4000" - name: PHX_HOST value: "towerops.net" - name: MIX_ENV value: "prod" - name: RELEASE_COOKIE valueFrom: secretKeyRef: name: towerops-secrets key: RELEASE_COOKIE - name: SECRET_KEY_BASE valueFrom: secretKeyRef: name: towerops-secrets key: SECRET_KEY_BASE - name: CLOAK_KEY valueFrom: secretKeyRef: name: towerops-secrets key: CLOAK_KEY - name: DATABASE_SSL value: "true" - name: DATABASE_SSL_VERIFY value: "false" envFrom: # Redis connection configured via towerops-redis secret - secretRef: name: towerops-redis - secretRef: name: towerops-db - secretRef: name: towerops-aws resources: requests: memory: "1.5Gi" cpu: "100m" limits: memory: "3Gi" cpu: "500m" startupProbe: httpGet: path: /health port: 4000 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 12 # 10s + (12 * 5s) = 70s max startup time livenessProbe: httpGet: path: /health port: 4000 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 readinessProbe: httpGet: path: /health port: 4000 initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 2 successThreshold: 2 # Require 2 consecutive successes before marking ready failureThreshold: 2 # Allow 1 failure before marking not ready