apiVersion: apps/v1 kind: Deployment metadata: name: portal namespace: portal labels: app: portal spec: replicas: 3 selector: matchLabels: app: portal template: metadata: labels: app: portal spec: containers: - name: portal image: yourregistry/portal:latest ports: - containerPort: 3000 name: http env: - name: NODE_ENV value: "production" - name: KEYCLOAK_URL valueFrom: configMapKeyRef: name: portal-config key: keycloak-url - name: CROSSPLANE_API_URL valueFrom: configMapKeyRef: name: portal-config key: crossplane-api-url - name: ARGOCD_URL valueFrom: configMapKeyRef: name: portal-config key: argocd-url resources: requests: cpu: 200m memory: 512Mi limits: cpu: 1000m memory: 2Gi livenessProbe: httpGet: path: /api/health port: 3000 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /api/health port: 3000 initialDelaySeconds: 10 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: portal namespace: portal spec: selector: app: portal ports: - port: 80 targetPort: 3000 name: http type: ClusterIP --- apiVersion: v1 kind: ConfigMap metadata: name: portal-config namespace: portal data: keycloak-url: "https://keycloak.sankofa.nexus" crossplane-api-url: "https://crossplane-api.crossplane-system.svc.cluster.local" argocd-url: "https://argocd.sankofa.nexus" grafana-url: "https://grafana.sankofa.nexus" loki-url: "https://loki.monitoring.svc.cluster.local:3100" --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: portal namespace: portal annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/ssl-redirect: "true" spec: ingressClassName: nginx tls: - hosts: - portal.sankofa.nexus secretName: portal-tls rules: - host: portal.sankofa.nexus http: paths: - path: / pathType: Prefix backend: service: name: portal port: number: 80