Going to Production
import { Aside } from ‘@astrojs/starlight/components’;
Checklist
Section titled “Checklist”- Postgres running outside the cluster (Neon, RDS, Cloud SQL) with SSL
-
DEV_AUTH_TOKENis empty — never set this in production - Auth0 SPA and API configured with your production domain
- TLS enabled on the ingress (cert-manager + Let’s Encrypt)
- Redis persistence enabled (AOF or RDB snapshot)
- Resource requests and limits set on all pods
- Liveness and readiness probes verified (
/healthz,/readyz) - Prometheus scraping enabled if running kube-prometheus-stack
Postgres
Section titled “Postgres”Use a managed Postgres service. The DATABASE_URL must include sslmode=require.
Run migrations as a pre-install/pre-upgrade Helm hook or a one-shot Job:
kubectl run migrate --rm -it \ --image=ghcr.io/play-quibble/trivia-api:latest \ --restart=Never \ --env="DATABASE_URL=${DATABASE_URL}" \ -- /app/api migrate upThe in-cluster Redis StatefulSet (enabled by default in the Helm chart) is sufficient for most deployments. For high availability, replace it with a managed Redis (DigitalOcean Managed Redis, Elasticache, Memorystore).
Secrets management
Section titled “Secrets management”Never put secrets in values.yaml. Use one of:
- Kubernetes Secret created out-of-band (
kubectl create secret) and referenced viaapi.existingSecret - External Secrets Operator syncing from AWS Secrets Manager, GCP Secret Manager, or Vault
- Sealed Secrets for GitOps-safe encrypted secret manifests
Scaling
Section titled “Scaling”The API is stateful per WebSocket connection. For multiple replicas, enable Redis Pub/Sub fan-out (planned feature) and add sticky sessions to the ingress:
nginx.ingress.kubernetes.io/affinity: "cookie"nginx.ingress.kubernetes.io/session-cookie-name: "quibble-session"Observability
Section titled “Observability”The API exposes Prometheus metrics at /metrics. Add a ServiceMonitor if you’re running the kube-prometheus-stack:
serviceMonitor: enabled: true namespace: monitoringIngress
Section titled “Ingress”The recommended setup uses ingress-nginx with cert-manager:
ingress: enabled: true className: nginx host: quibble.yourdomain.com annotations: cert-manager.io/cluster-issuer: letsencrypt-prod tls: enabled: true issuer: letsencrypt-prodAll traffic routes through one ingress:
/api/*→ API service/*→ Web service