Kubernetes
This guide covers deploying Goiabada to a Kubernetes cluster.
What Goiabada needs
Section titled “What Goiabada needs”Regardless of your Kubernetes setup, Goiabada requires:
| Requirement | Details |
|---|---|
| HTTPS access | Both auth server and admin console must be accessible via HTTPS |
| Two hostnames | Separate domains/subdomains for auth server and admin console |
| Shared database | MySQL, PostgreSQL, or SQL Server (SQLite not supported - pods need a shared database) |
| Empty database | For fresh deployments, the database must be empty - Goiabada seeds it with OAuth clients configured for your specific URLs |
| Proxy headers | The generated manifests set TRUST_PROXY_HEADERS=true for proper client IP detection behind an ingress |
| Large proxy buffers | OAuth responses have large headers; nginx needs proxy-buffer-size: 128k (the setup wizard configures this automatically) |
Architecture
Section titled “Architecture”Internet → Gateway/Ingress (HTTPS/TLS) → { auth.example.com → goiabada-authserver Service (9090) → Pods admin.example.com → goiabada-adminconsole Service (9091) → Pods}The setup wizard generates:
- Namespace: Isolated environment for Goiabada resources
- Secret: Database password, session keys, OAuth client secret (base64 encoded)
- ConfigMap: URLs, database connection details, app configuration
- Deployments: Auth server and admin console with health checks and resource limits
- Services: ClusterIP services for internal routing
- Ingress: External access with TLS termination
Prerequisites
Section titled “Prerequisites”- A Kubernetes cluster
kubectlconfigured to access your cluster- A database server (MySQL, PostgreSQL, or SQL Server) - can be in-cluster or external
- Two domain names for auth server and admin console
Example setup: ingress-nginx + cert-manager
Section titled “Example setup: ingress-nginx + cert-manager”This is the recipe we tested. Adapt as needed for your environment.
Step 1: Install ingress-nginx
Section titled “Step 1: Install ingress-nginx”The install command below modifies externalTrafficPolicy from Local to Cluster for better compatibility with cloud LoadBalancers.
curl -s https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.14.0/deploy/static/provider/cloud/deploy.yaml \ | sed 's/externalTrafficPolicy: Local/externalTrafficPolicy: Cluster/' \ | kubectl apply -f -Wait for it to be ready:
kubectl wait --namespace ingress-nginx \ --for=condition=ready pod \ --selector=app.kubernetes.io/component=controller \ --timeout=120sStep 2: Install cert-manager
Section titled “Step 2: Install cert-manager”kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.1/cert-manager.yamlWait for it to be ready:
kubectl wait --namespace cert-manager \ --for=condition=ready pod \ --selector=app.kubernetes.io/instance=cert-manager \ --timeout=120sStep 3: Create ClusterIssuer for Let’s Encrypt
Section titled “Step 3: Create ClusterIssuer for Let’s Encrypt”Save as letsencrypt-issuer.yaml:
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-prodspec: acme: server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: nginxApply it:
kubectl apply -f letsencrypt-issuer.yamlStep 4: Configure your database
Section titled “Step 4: Configure your database”Goiabada needs a shared database (SQLite is not supported for Kubernetes). Options include:
- Managed services: AWS RDS, Google Cloud SQL, Azure Database, Supabase, PlanetScale, Neon
- Self-hosted: Deploy MySQL/PostgreSQL in your cluster or on a VM
Example (Supabase): Use the connection pooler (not direct connection):
Host: aws-0-us-east-1.pooler.supabase.comPort: 5432User: postgres.your-project-refStep 5: Generate and deploy Goiabada
Section titled “Step 5: Generate and deploy Goiabada”Use the setup wizard:
./goiabada-setup- Select “3. Kubernetes cluster”
- Choose your database type
- Enter your domain names (e.g.,
https://auth.example.com) - Enter your Kubernetes namespace (default:
goiabada) - Configure admin credentials
- Enter your database connection details
The wizard will:
- Test database connectivity
- Check if the database is empty (warns you if it contains existing Goiabada data)
- Generate all Kubernetes manifests in a single file
Deploy:
kubectl apply -f goiabada-k8s.yamlStep 6: Configure DNS
Section titled “Step 6: Configure DNS”After deploying, get the LoadBalancer IP:
kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}'Create DNS A records pointing to this IP:
| Record | Value |
|---|---|
auth.example.com | <ADDRESS> |
admin.example.com | <ADDRESS> |
Step 7: Verify deployment
Section titled “Step 7: Verify deployment”# Check podskubectl get pods -n goiabada
# Check Ingress status (should show ADDRESS)kubectl get ingress -n goiabada
# Check certificates (should show READY=True after DNS propagates)kubectl get certificates -n goiabadaExpected output:
NAME READY STATUS RESTARTS AGEgoiabada-authserver-xxxxx-xxxxx 1/1 Running 0 1mgoiabada-adminconsole-xxxxx-xxxxx 1/1 Running 0 1mTroubleshooting
Section titled “Troubleshooting”Certificates not issuing
Section titled “Certificates not issuing”# Check certificate statuskubectl describe certificate -n goiabada
# Check challengeskubectl get challenges -n goiabadakubectl describe challenges -n goiabada| Problem | Solution |
|---|---|
| DNS not resolving | Verify DNS A records point to ingress-nginx LoadBalancer IP |
| Port 80 not accessible | Check firewall rules; ACME HTTP-01 needs port 80 |
| Challenge timeout | See “Connectivity Issues” below |
Connectivity issues (port 80 not responding)
Section titled “Connectivity issues (port 80 not responding)”Some cloud providers have issues with externalTrafficPolicy: Local on LoadBalancer services. The install command in Step 1 changes this to Cluster to avoid the issue.
If you installed ingress-nginx without the sed modification, patch it:
kubectl patch svc ingress-nginx-controller -n ingress-nginx \ -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'Then delete any failed certificate challenges to trigger a retry:
kubectl delete challenges -n goiabada --all502 Bad Gateway after login
Section titled “502 Bad Gateway after login”If you see a 502 error after entering credentials (typically at /auth/completed), this is caused by nginx’s proxy buffer being too small for OAuth’s large response headers.
Solution: Ensure your Ingress has the proxy buffer annotation:
metadata: annotations: nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"The setup wizard adds this automatically. If you created Ingress resources manually, add this annotation and reapply.
OAuth “Invalid redirect_uri” error
Section titled “OAuth “Invalid redirect_uri” error”This means the database has OAuth clients configured for different URLs than you’re using.
Solutions:
- Use a fresh/empty database
- Use the same URLs as the previous deployment
- Manually update
redirect_urisin theclientstable
Database connection errors
Section titled “Database connection errors”# Check pod logskubectl logs -n goiabada deployment/goiabada-authserver
# Test connectivity from within clusterkubectl run -it --rm debug --image=busybox --restart=Never -- \ nc -zv your-db-host 5432Pods in CrashLoopBackOff
Section titled “Pods in CrashLoopBackOff”kubectl logs -n goiabada deployment/goiabada-authserver --previousCommon causes:
- Database connection failed
- Invalid configuration values
- Database not empty with mismatched URLs
High availability
Section titled “High availability”For production deployments:
Scale replicas
Section titled “Scale replicas”kubectl scale deployment goiabada-authserver -n goiabada --replicas=3kubectl scale deployment goiabada-adminconsole -n goiabada --replicas=2Resource limits
Section titled “Resource limits”The generated manifests include default limits. Adjust based on your load:
resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m"Health endpoints
Section titled “Health endpoints”Both services expose health checks used by Kubernetes probes:
- Auth server:
http://goiabada-authserver:9090/health - Admin console:
http://goiabada-adminconsole:9091/health
Updating Goiabada
Section titled “Updating Goiabada”- Update image tags in your manifest or regenerate with the setup wizard
- Apply changes:
Terminal window kubectl apply -f goiabada-k8s.yaml - Monitor rollout:
Terminal window kubectl rollout status deployment/goiabada-authserver -n goiabada