# Initial Deployment Guide Follow these steps to deploy TurboVault to Kubernetes for the first time. ## Prerequisites - ✅ Code pushed to GitHub - ✅ PostgreSQL database ready (host, user, password) - ✅ kubectl configured for k3s cluster (100.101.31.99:6443) - ✅ Docker installed locally - ✅ Gitea account at gitea.kazcloud.dev --- ## Step 1: Build and Push Initial Image Since GitHub Actions hasn't run yet, build the first image manually: ```bash # Build image docker build -t gitea.kazcloud.dev/ryan/turbovault-app:v1.0.0 . # Login to Gitea registry docker login gitea.kazcloud.dev # Username: ryankazokas # Password: # Push image docker push gitea.kazcloud.dev/ryan/turbovault-app:v1.0.0 # Also tag as latest docker tag gitea.kazcloud.dev/ryan/turbovault-app:v1.0.0 \ gitea.kazcloud.dev/ryan/turbovault-app:latest docker push gitea.kazcloud.dev/ryan/turbovault-app:latest ``` ✅ **Verify:** Check Gitea packages at `gitea.kazcloud.dev/ryankazokas/-/packages` --- ## Step 2: Configure Kubernetes Secrets ```bash # Copy template cp k8s/secrets.yaml.example k8s/secrets.yaml # Generate Rails secret key rails secret # Copy the output # Edit secrets file nano k8s/secrets.yaml ``` **Add these values in `k8s/secrets.yaml`:** ```yaml apiVersion: v1 kind: Secret metadata: name: turbovault-secrets namespace: turbovault type: Opaque stringData: SECRET_KEY_BASE: "" DATABASE_PASSWORD: "your-postgres-password" # Optional: IGDB integration IGDB_CLIENT_ID: "your-igdb-client-id" IGDB_CLIENT_SECRET: "your-igdb-client-secret" # Optional: Email (for password resets) SMTP_ADDRESS: "smtp.example.com" SMTP_PORT: "587" SMTP_USERNAME: "user@example.com" SMTP_PASSWORD: "smtp-password" ``` --- ## Step 3: Configure Database Connection Edit `k8s/configmap.yaml`: ```yaml apiVersion: v1 kind: ConfigMap metadata: name: turbovault-config namespace: turbovault data: RAILS_ENV: "production" DATABASE_HOST: "your-postgres-host" DATABASE_NAME: "turbovault_production" DATABASE_USERNAME: "turbovault" RAILS_LOG_TO_STDOUT: "true" RAILS_SERVE_STATIC_FILES: "true" ``` **Replace:** - `your-postgres-host` - Your PostgreSQL server hostname/IP - Database name and username if different --- ## Step 4: Deploy to Kubernetes Run the automated deployment script: ```bash ./scripts/deploy-k8s.sh ``` **When prompted for registry credentials:** - Registry: `gitea.kazcloud.dev` - Username: `ryankazokas` - Password: `` **The script will:** 1. Create namespace 2. Apply configmap 3. Apply secrets 4. Run database migration job 5. Deploy application 6. Create service 7. Create ingress --- ## Step 5: Verify Deployment ```bash # Check all resources kubectl get all -n turbovault # Check pods are running kubectl get pods -n turbovault # View logs kubectl logs -f -l app=turbovault -n turbovault # Check migration job completed kubectl logs job/turbovault-migrate -n turbovault ``` **Expected output:** ``` NAME READY STATUS RESTARTS AGE pod/turbovault-xxxxxxxxxx-xxxxx 1/1 Running 0 2m pod/turbovault-xxxxxxxxxx-xxxxx 1/1 Running 0 2m ``` --- ## Step 6: Access Application ### Option A: Port Forward (Testing) ```bash kubectl port-forward svc/turbovault-service 3000:80 -n turbovault ``` Visit: http://localhost:3000 ### Option B: Ingress (Production) Edit `k8s/ingress.yaml` with your domain and apply: ```bash kubectl apply -f k8s/ingress.yaml ``` Visit: https://your-domain.com --- ## Step 7: Configure GitHub Secrets Now set up automated deployments for future updates. See [docs/GITHUB_SECRETS.md](docs/GITHUB_SECRETS.md) for detailed instructions. **Required secrets (add at https://github.com/ryankazokas/turbovault-app/settings/secrets/actions):** 1. `GITEA_USERNAME` - Your Gitea username 2. `GITEA_TOKEN` - Gitea access token (Settings → Applications) 3. `TAILSCALE_CLIENT_ID` - Tailscale OAuth client ID 4. `TAILSCALE_CLIENT_SECRET` - Tailscale OAuth client secret 5. `KUBECONFIG` - Base64-encoded kubeconfig (`cat ~/.kube/config | base64 -w 0`) --- ## Step 8: Test Automated Deployment After GitHub secrets are configured: ```bash # Create a test tag git tag v1.0.1 git push origin v1.0.1 ``` Watch at: https://github.com/ryankazokas/turbovault-app/actions GitHub Actions will: 1. Build Docker image 2. Push to Gitea registry 3. Connect via Tailscale 4. Deploy to Kubernetes --- ## Troubleshooting ### Pods in CrashLoopBackOff ```bash # View logs kubectl logs -l app=turbovault -n turbovault # Common issues: # - Database connection failed (check configmap/secrets) # - Missing SECRET_KEY_BASE (check secrets) # - Migration not run (check migration job logs) ``` ### Migration Job Failed ```bash # View migration logs kubectl logs job/turbovault-migrate -n turbovault # Re-run migration kubectl delete job turbovault-migrate -n turbovault kubectl apply -f k8s/migrate-job.yaml ``` ### Can't Pull Image ```bash # Check image pull secret kubectl get secrets -n turbovault # Re-run deploy script to create secret ./scripts/deploy-k8s.sh ``` ### Database Connection Failed ```bash # Test from pod kubectl exec -it deployment/turbovault -n turbovault -- \ rails runner "puts ActiveRecord::Base.connection.execute('SELECT 1').first" # Check environment variables kubectl exec -it deployment/turbovault -n turbovault -- env | grep DATABASE ``` --- ## Next Steps After successful initial deployment: 1. ✅ Application is running in Kubernetes 2. ✅ GitHub Actions configured for automated deployments 3. 🚀 **Daily workflow:** Just push tags to deploy! ```bash # Make changes git add . git commit -m "Feature: new functionality" git push # Deploy git tag v1.0.2 git push origin v1.0.2 # GitHub Actions automatically builds and deploys! ✅ ``` --- ## Quick Reference ```bash # View status kubectl get all -n turbovault # View logs kubectl logs -f -l app=turbovault -n turbovault # Restart deployment kubectl rollout restart deployment/turbovault -n turbovault # Rollback deployment kubectl rollout undo deployment/turbovault -n turbovault # Delete everything (start over) kubectl delete namespace turbovault ``` --- ## Files You Modified Keep these files safe (they're gitignored): - `k8s/secrets.yaml` - Contains sensitive data (SECRET_KEY_BASE, passwords) - `~/.kube/config` - Your Kubernetes access **DO NOT** commit these to git! --- **Need help?** Check logs first: ```bash kubectl describe pod -l app=turbovault -n turbovault kubectl logs -l app=turbovault -n turbovault ```