# Quickstart: Kubernetes Production Deployment ## Before You Apply 1. Store API secrets in Vault at `reactbin/api/config` (KV v2): ``` DATABASE_URL = postgresql+asyncpg://reactbin:@:5432/reactbin JWT_SECRET_KEY = OWNER_USERNAME = OWNER_PASSWORD = S3_ENDPOINT_URL = http://minio.reactbin.svc.cluster.local:9000 S3_BUCKET_NAME = reactbin S3_ACCESS_KEY_ID = S3_SECRET_ACCESS_KEY = API_BASE_URL = https:// API_DOCS_ENABLED = false ``` 2. Store MinIO credentials in Vault at `reactbin/minio/credentials` (KV v2): ``` MINIO_ROOT_USER = MINIO_ROOT_PASSWORD = ``` 3. Create a Vault Kubernetes auth role bound to the `default` service account in the `reactbin` namespace with read access to both paths above. 4. Confirm DNS resolves to the cluster ingress IP and the `letsencrypt-prod` ClusterIssuer exists. ## Deploy ```bash # Substitute the real image tags sed -i 's|reactbin-api:latest|reactbin-api:v1.0.0|g' k8s/api/deployment.yaml sed -i 's|reactbin-ui:latest|reactbin-ui:v1.0.0|g' k8s/ui/deployment.yaml # Apply everything kubectl apply -f k8s/ ``` ## Verify ```bash # Watch pods come up (init container runs first on the API pod) kubectl get pods -n reactbin -w # API health curl -sf https:///api/v1/health && echo "API OK" # UI reachable curl -sf -o /dev/null -w "%{http_code}\n" https:/// # Docs correctly gated curl -o /dev/null -w "%{http_code}\n" https:///docs # → 404 curl -o /dev/null -w "%{http_code}\n" https:///redoc # → 404 # Check migration init container ran kubectl logs -n reactbin -l app=api -c alembic-migrate ``` ## Scenario: Migration fails on deploy ```bash # Pod will be stuck in Init state kubectl get pods -n reactbin # NAME READY STATUS RESTARTS # api-xxx-yyy 0/1 Init:CrashLoopBackOff 2 # See why kubectl logs -n reactbin -c alembic-migrate # Fix the issue (e.g. correct DATABASE_URL in Vault, wait for VSO to resync) # Then delete the pod to force a fresh rollout kubectl rollout restart deployment/api -n reactbin ``` ## Scenario: Update to a new image version ```bash kubectl set image deployment/api api=reactbin-api:v1.1.0 -n reactbin kubectl set image deployment/ui ui=reactbin-ui:v1.1.0 -n reactbin # Kubernetes rolls out new pods; init container runs migrations before traffic switches ``` ## Scenario: Restore after MinIO pod restart MinIO uses a PersistentVolumeClaim. Pod restarts do not affect stored data. Verify: ```bash kubectl delete pod -n reactbin minio-0 kubectl get pods -n reactbin -w # minio-0 restarts, PVC reattaches # Previously uploaded images should still be accessible via the API ```