# operator — Nuxt SSR internal control plane on operator.dezky.eu. Platform # admins only (Authentik dezky-operator app is gated by the # dezky-platform-admins group policy). Talks to platform-api over the cluster # network via its server routes (PLATFORM_API_INTERNAL_URL), forwarding the # signed-in operator's access token. Authenticates through Authentik (OIDC), # using a DIFFERENT client (dezky-operator) than the customer portal. apiVersion: apps/v1 kind: Deployment metadata: name: operator namespace: dezky-apps labels: app.kubernetes.io/name: operator app.kubernetes.io/part-of: dezky spec: # Single replica until OIDC sessions move to shared storage: nuxt-oidc-auth # keeps sessions in per-pod memory, so with >1 replica every request that # lands on the pod that did NOT handle the login gets 401. TODO: nitro # session storage on the dezky-data Redis, then scale back up. replicas: 1 selector: matchLabels: app.kubernetes.io/name: operator template: metadata: labels: app.kubernetes.io/name: operator spec: containers: - name: operator # CI pins this to the commit SHA at deploy time (kustomize edit set image # in .gitea/workflows/ci.yml); :latest here is the fallback. image: git.lastcloud.io/ronnibaslund/dezky/operator:latest imagePullPolicy: IfNotPresent ports: - name: http containerPort: 3000 env: - name: HOST value: "0.0.0.0" - name: PORT value: "3000" - name: NUXT_PUBLIC_OPERATOR_URL value: https://operator.dezky.eu # Cluster-internal address of platform-api (operator server routes # forward the operator's access token to it). - name: PLATFORM_API_INTERNAL_URL value: http://platform-api.dezky-apps.svc.cluster.local:3001 # OIDC client id/secret, NUXT_OIDC_REDIRECT_URI, NUXT_PUBLIC_AUTH_URL # and the session secret come from the Secret. The OIDC client secret # MUST equal authentik-secret.OPERATOR_OIDC_CLIENT_SECRET. envFrom: - secretRef: name: operator-secrets resources: requests: cpu: 100m memory: 192Mi limits: memory: 512Mi readinessProbe: tcpSocket: port: http initialDelaySeconds: 10 periodSeconds: 15 livenessProbe: tcpSocket: port: http initialDelaySeconds: 30 periodSeconds: 30 --- apiVersion: v1 kind: Service metadata: name: operator namespace: dezky-apps labels: app.kubernetes.io/name: operator spec: selector: app.kubernetes.io/name: operator ports: - name: http port: 3000 targetPort: http --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: operator namespace: dezky-apps annotations: cert-manager.io/cluster-issuer: letsencrypt-prod # Serve on :80 too so the cert-manager ACME HTTP-01 solver can answer on # port 80; the redirect-https middleware bounces all other traffic to HTTPS. traefik.ingress.kubernetes.io/router.entrypoints: web,websecure traefik.ingress.kubernetes.io/router.middlewares: dezky-apps-redirect-https@kubernetescrd spec: ingressClassName: traefik tls: - hosts: - operator.dezky.eu secretName: operator-dezky-eu-tls rules: - host: operator.dezky.eu http: paths: - path: / pathType: Prefix backend: service: name: operator port: number: 3000