# Staging Deployment (Phase 10-07, Task 2) ## Overview This document describes the deployment of Gravl services to the Kubernetes staging environment. ## Prerequisites - Staging namespace configured (see `setup-staging.sh` / Task 1) - `kubectl` installed and configured for staging cluster - Docker images built and available in registry or local cache ## Deployment Process ### 1. PostgreSQL StatefulSet - **Image**: `postgres:15-alpine` - **Replicas**: 1 (staging only) - **PVC**: 10Gi volume for data persistence - **Health Check**: Liveness and readiness probes on pg_isready command - **Expected Time**: 10-30 seconds to reach Ready state ```bash kubectl get statefulsets -n gravl-staging kubectl describe statefulset gravl-db -n gravl-staging ``` ### 2. Backend Deployment - **Image**: `gravl-backend:latest` (from registry or local) - **Replicas**: 1 (staging only, production uses 3) - **Port**: 3001 (HTTP) - **Environment Variables**: Sourced from ConfigMap and Secrets - **Health Check**: HTTP liveness probe on `/api/health` endpoint - **Expected Time**: 5-15 seconds to reach Ready state (after DB is ready) ```bash kubectl get deployments -n gravl-staging kubectl logs -f deployment/gravl-backend -n gravl-staging ``` ### 3. Frontend Deployment - **Image**: `gravl-frontend:latest` (from registry or local) - **Replicas**: 1 (staging only, production uses 3) - **Port**: 80 (HTTP) - **Content**: Served by Nginx static file server - **Health Check**: HTTP liveness probe on `/` endpoint - **Expected Time**: 3-10 seconds to reach Ready state ```bash kubectl get deployments -n gravl-staging kubectl logs -f deployment/gravl-frontend -n gravl-staging ``` ### 4. Ingress Configuration - **Host**: `gravl-staging.homelab.local` - **TLS**: Not configured for staging (HTTP only) - **Routing**: - `/api/*` → backend:3001 - `/*` → frontend:80 - **Annotations**: CORS enabled, compression enabled ```bash kubectl get ingress -n gravl-staging kubectl describe ingress gravl-ingress -n gravl-staging ``` ## Deployment Commands ### Option 1: Use the automation script ```bash ./scripts/deploy-staging.sh ``` ### Option 2: Manual kubectl apply ```bash # Deploy all services at once kubectl apply -f k8s/deployments/postgresql.yaml \ -f k8s/deployments/gravl-backend.yaml \ -f k8s/deployments/gravl-frontend.yaml \ -f k8s/deployments/ingress-nginx.yaml ``` Note: Replace `gravl-prod` namespace with `gravl-staging` in the manifests. ## Verification ### Check pod status ```bash kubectl get pods -n gravl-staging kubectl describe pod -n gravl-staging ``` Expected output (all pods Ready 1/1): ``` NAME READY STATUS RESTARTS AGE gravl-db-0 1/1 Running 0 2m gravl-backend-xxxxxxxx-xxxxx 1/1 Running 0 1m gravl-frontend-xxxxxxxx-xxxxx 1/1 Running 0 1m ``` ### Check service connectivity From inside the cluster (in a debug pod): ```bash kubectl run -it --image=curlimages/curl:latest debug -n gravl-staging -- sh curl http://gravl-backend:3001/api/health curl http://gravl-frontend/ ``` From outside the cluster: ```bash curl http://gravl-staging.homelab.local/api/health curl http://gravl-staging.homelab.local/ ``` ### Check logs ```bash # Backend logs kubectl logs -n gravl-staging -l component=backend # Frontend logs kubectl logs -n gravl-staging -l component=frontend # PostgreSQL logs kubectl logs -n gravl-staging -l component=database ``` ## Troubleshooting ### Pod stuck in Pending - Check node resources: `kubectl describe node ` - Check PVC availability: `kubectl get pvc -n gravl-staging` ### Pod crashed (CrashLoopBackOff) - Check logs: `kubectl logs -n gravl-staging -p ` - Check resource limits: `kubectl describe pod -n gravl-staging` - Verify secrets are applied: `kubectl get secrets -n gravl-staging` ### Service not accessible via Ingress - Check Ingress status: `kubectl describe ingress gravl-ingress -n gravl-staging` - Check DNS: `nslookup gravl-staging.homelab.local` - Verify Nginx Ingress Controller is running: `kubectl get pods -n ingress-nginx` ## Next Steps 1. **Run integration tests** (Task 3) 2. **Set up monitoring** (Task 4): Prometheus, Grafana, Loki 3. **Perform load testing** (Task 5): k6 script to verify performance 4. **Production readiness review** (Task 5): Security, checklist, rollback procedures ## Success Criteria ✓ All pods (PostgreSQL, backend, frontend) running and Ready ✓ No pod restarts in the last 5 minutes ✓ Service-to-service communication verified ✓ Ingress accessible from outside cluster ✓ API health endpoint responds with 200 OK --- **Document Version**: 1.0 **Last Updated**: 2026-03-04 **Status**: Task 2 Complete