# MasterOne on the prod cluster — Longhorn 3-replica storage. # Portal + postgres; public entry via hostPort 443 on workernode03 (only free 443). apiVersion: v1 kind: Namespace metadata: name: masterone --- apiVersion: v1 kind: PersistentVolumeClaim metadata: {name: masterone-postgres, namespace: masterone} spec: accessModes: [ReadWriteOnce] storageClassName: longhorn resources: {requests: {storage: 10Gi}} --- apiVersion: v1 kind: PersistentVolumeClaim metadata: {name: masterone-uploads, namespace: masterone} spec: accessModes: [ReadWriteOnce] storageClassName: longhorn resources: {requests: {storage: 10Gi}} --- apiVersion: apps/v1 kind: Deployment metadata: {name: postgres, namespace: masterone} spec: replicas: 1 strategy: {type: Recreate} selector: {matchLabels: {app: postgres}} template: metadata: {labels: {app: postgres}} spec: containers: - name: postgres image: postgres:17-alpine ports: [{containerPort: 5432}] env: - {name: POSTGRES_DB, value: masterone_portal} - {name: POSTGRES_USER, value: masterone} - name: POSTGRES_PASSWORD valueFrom: {secretKeyRef: {name: masterone-secrets, key: POSTGRES_PASSWORD}} volumeMounts: [{name: data, mountPath: /var/lib/postgresql/data, subPath: pgdata}] readinessProbe: exec: {command: ["pg_isready","-U","masterone","-d","masterone_portal"]} initialDelaySeconds: 5 periodSeconds: 5 volumes: - name: data persistentVolumeClaim: {claimName: masterone-postgres} --- apiVersion: v1 kind: Service metadata: {name: postgres, namespace: masterone} spec: selector: {app: postgres} ports: [{port: 5432, targetPort: 5432}] --- apiVersion: apps/v1 kind: Deployment metadata: {name: portal, namespace: masterone} spec: replicas: 1 strategy: {type: Recreate} selector: {matchLabels: {app: portal}} template: metadata: {labels: {app: portal}} spec: containers: - name: portal image: masterone-portal:k8s3 imagePullPolicy: IfNotPresent ports: [{containerPort: 8095}] envFrom: [{secretRef: {name: masterone-secrets}}] env: - {name: PORTAL_MASTERONE_ROOT, value: /masterone} - name: DATABASE_URL value: postgresql://masterone:$(POSTGRES_PASSWORD)@postgres.masterone.svc.cluster.local/masterone_portal - {name: PORTAL_COOKIE_SECURE, value: "1"} volumeMounts: [{name: uploads, mountPath: /app/uploads}] readinessProbe: {httpGet: {path: /healthz, port: 8095}, initialDelaySeconds: 15, periodSeconds: 10} livenessProbe: {httpGet: {path: /healthz, port: 8095}, initialDelaySeconds: 30, periodSeconds: 30} resources: requests: {memory: 512Mi, cpu: 100m} limits: {memory: 2Gi} volumes: - name: uploads persistentVolumeClaim: {claimName: masterone-uploads} --- apiVersion: v1 kind: Service metadata: {name: portal, namespace: masterone} spec: selector: {app: portal} ports: [{port: 8095, targetPort: 8095}] --- # Public entry: nginx on node03 hostPort 443 (plain HTTP — TLS terminates at Caddy on the mgmt VPC) apiVersion: v1 kind: ConfigMap metadata: {name: ingress-conf, namespace: masterone} data: default.conf: | server { listen 443 ssl; ssl_certificate /etc/nginx/tls/tls.crt; ssl_certificate_key /etc/nginx/tls/tls.key; client_max_body_size 100m; location / { proxy_pass http://portal.masterone.svc.cluster.local:8095; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 300s; } } --- apiVersion: apps/v1 kind: Deployment metadata: {name: edge-ingress, namespace: masterone} spec: replicas: 1 strategy: {type: Recreate} spec: replicas: 1 selector: {matchLabels: {app: edge-ingress}} template: metadata: {labels: {app: edge-ingress}} spec: nodeSelector: {kubernetes.io/hostname: workernode03.hopeamulets.com} containers: - name: nginx image: nginx:1.27-alpine ports: [{containerPort: 443, hostPort: 443}] volumeMounts: - {name: conf, mountPath: /etc/nginx/conf.d} - {name: tls, mountPath: /etc/nginx/tls} volumes: - name: conf configMap: {name: ingress-conf} - name: tls secret: {secretName: edge-tls}