- Switch from Gitea to GitHub Container Registry (ghcr.io) - Add GitHub Actions workflow with Tailscale connectivity - Update k8s manifests for cloud nodes and Traefik ingress - Configure for turbo.kazcloud.dev domain - Test deployment with home page text change
6.5 KiB
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:
# 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: <your-gitea-token>
# 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
# 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:
apiVersion: v1
kind: Secret
metadata:
name: turbovault-secrets
namespace: turbovault
type: Opaque
stringData:
SECRET_KEY_BASE: "<paste-output-from-rails-secret>"
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:
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:
./scripts/deploy-k8s.sh
When prompted for registry credentials:
- Registry:
gitea.kazcloud.dev - Username:
ryankazokas - Password:
<your-gitea-token>
The script will:
- Create namespace
- Apply configmap
- Apply secrets
- Run database migration job
- Deploy application
- Create service
- Create ingress
Step 5: Verify Deployment
# 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)
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:
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 for detailed instructions.
Required secrets (add at https://github.com/ryankazokas/turbovault-app/settings/secrets/actions):
GITEA_USERNAME- Your Gitea usernameGITEA_TOKEN- Gitea access token (Settings → Applications)TAILSCALE_CLIENT_ID- Tailscale OAuth client IDTAILSCALE_CLIENT_SECRET- Tailscale OAuth client secretKUBECONFIG- Base64-encoded kubeconfig (cat ~/.kube/config | base64 -w 0)
Step 8: Test Automated Deployment
After GitHub secrets are configured:
# 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:
- Build Docker image
- Push to Gitea registry
- Connect via Tailscale
- Deploy to Kubernetes
Troubleshooting
Pods in CrashLoopBackOff
# 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
# 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
# Check image pull secret
kubectl get secrets -n turbovault
# Re-run deploy script to create secret
./scripts/deploy-k8s.sh
Database Connection Failed
# 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:
- ✅ Application is running in Kubernetes
- ✅ GitHub Actions configured for automated deployments
- 🚀 Daily workflow: Just push tags to deploy!
# 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
# 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:
kubectl describe pod -l app=turbovault -n turbovault
kubectl logs -l app=turbovault -n turbovault