Files
turbovault-app/docs/DEPLOYMENT.md
2026-03-28 19:30:27 -04:00

7.7 KiB

TurboVault Deployment Guide

Complete guide for deploying TurboVault to production.

Table of Contents

  1. GitHub Setup
  2. Kubernetes Deployment
  3. Database Setup
  4. DNS & SSL
  5. Monitoring

GitHub Setup

Push to GitHub

# Run the automated setup script
./scripts/setup-github.sh

# Or manually:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/turbovault.git
git push -u origin main

Set Up GitHub Actions (Optional)

Create .github/workflows/ci.yml for automated testing and building:

name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - uses: actions/checkout@v3
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.3'
          bundler-cache: true
      - run: bundle exec rails db:test:prepare
      - run: bundle exec rails test

Kubernetes Deployment

Prerequisites

  • k3s/k8s cluster running
  • kubectl configured
  • Docker installed
  • PostgreSQL database (in-cluster or external)

Quick Deploy

# Automated deployment
./scripts/deploy-k8s.sh

Manual Deployment

# 1. Login to Gitea registry
docker login gitea.example.com

# 2. Build and push Docker image
docker build -t gitea.example.com/username/turbovault:latest .
docker push gitea.example.com/username/turbovault:latest

# 3. Create Gitea registry secret in k8s
kubectl create secret docker-registry gitea-registry \
  --docker-server=gitea.example.com \
  --docker-username=your-username \
  --docker-password=your-gitea-token \
  --docker-email=your-email@example.com \
  --namespace=turbovault

# 2. Create secrets
cp k8s/secrets.yaml.example k8s/secrets.yaml
# Edit k8s/secrets.yaml with your values

# 3. Generate Rails secret
rails secret
# Copy output to k8s/secrets.yaml SECRET_KEY_BASE

# 4. Deploy to k8s
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secrets.yaml
kubectl apply -f k8s/migrate-job.yaml
kubectl wait --for=condition=complete --timeout=300s job/turbovault-migrate -n turbovault
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml

Update Image Reference

Edit k8s/deployment.yaml and k8s/migrate-job.yaml with your registry path:

# For public registries (GitHub Container Registry, Docker Hub public)
# No imagePullSecrets needed!
image: ghcr.io/your-username/turbovault:latest

# For private registries, add imagePullSecrets:
imagePullSecrets:
- name: registry-secret

image: your-registry.com/turbovault:latest

Default: Use GitHub Container Registry (ghcr.io) - free and built-in.
See: k8s/README.md for registry setup details.


Database Setup

Option 1: External PostgreSQL

Use an external PostgreSQL instance (recommended for production):

  1. Create database and user:

    CREATE DATABASE turbovault_production;
    CREATE USER turbovault WITH PASSWORD 'your-secure-password';
    GRANT ALL PRIVILEGES ON DATABASE turbovault_production TO turbovault;
    
  2. Update k8s/configmap.yaml:

    DATABASE_HOST: "your-postgres-host.example.com"
    DATABASE_PORT: "5432"
    DATABASE_NAME: "turbovault_production"
    DATABASE_USERNAME: "turbovault"
    
  3. Update k8s/secrets.yaml:

    DATABASE_PASSWORD: "your-secure-password"
    

Option 2: In-Cluster PostgreSQL

Deploy PostgreSQL in your cluster using Helm:

# Add Bitnami repo
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# Install PostgreSQL
helm install postgres bitnami/postgresql \
  --namespace turbovault \
  --set auth.database=turbovault_production \
  --set auth.username=turbovault \
  --set auth.password=changeme \
  --set primary.persistence.size=10Gi

# Connection details
DATABASE_HOST: postgres-postgresql
DATABASE_PORT: 5432

DNS & SSL

Configure DNS

Point your domain to your cluster's ingress:

# Get ingress IP
kubectl get ingress -n turbovault

# Add A record
turbovault.example.com -> YOUR_INGRESS_IP

Enable SSL with cert-manager

# Install cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

# Create ClusterIssuer
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
EOF

Update k8s/ingress.yaml:

metadata:
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - turbovault.example.com
    secretName: turbovault-tls

Monitoring

Health Checks

# Check pod health
kubectl get pods -n turbovault

# Check application health
kubectl port-forward svc/turbovault-service 3000:80 -n turbovault
# Visit http://localhost:3000/up

View Logs

# All pods
kubectl logs -f -l app=turbovault -n turbovault

# Specific pod
kubectl logs -f turbovault-xxxxx-xxxxx -n turbovault

# Previous logs (if crashed)
kubectl logs --previous turbovault-xxxxx-xxxxx -n turbovault

Common Issues

Pods not starting:

kubectl describe pod -l app=turbovault -n turbovault

Database connection failed:

# Test connection
kubectl run -it --rm debug --image=postgres:15 --restart=Never -n turbovault -- \
  psql -h postgres-postgresql -U turbovault -d turbovault_production

Migration failed:

kubectl logs job/turbovault-migrate -n turbovault

Scaling

Horizontal Scaling

# Scale to 3 replicas
kubectl scale deployment turbovault --replicas=3 -n turbovault

# Auto-scaling (HPA)
kubectl autoscale deployment turbovault \
  --cpu-percent=70 \
  --min=2 \
  --max=10 \
  -n turbovault

Vertical Scaling

Edit k8s/deployment.yaml:

resources:
  requests:
    memory: "1Gi"
    cpu: "500m"
  limits:
    memory: "2Gi"
    cpu: "2000m"

Backup & Restore

Database Backup

# Automated backup (cronjob)
kubectl create cronjob pg-backup \
  --image=postgres:15 \
  --schedule="0 2 * * *" \
  --restart=Never \
  -n turbovault \
  -- /bin/sh -c "pg_dump -h postgres-postgresql -U turbovault turbovault_production | gzip > /backup/turbovault-$(date +%Y%m%d).sql.gz"

Full Backup

# Backup all k8s resources
kubectl get all -n turbovault -o yaml > turbovault-backup.yaml

# Backup secrets (encrypted)
kubectl get secrets -n turbovault -o yaml > secrets-backup.yaml

Security Best Practices

  1. Use Kubernetes Secrets (or Sealed Secrets)
  2. Enable HTTPS/TLS
  3. Set resource limits
  4. Use non-root container user
  5. Enable Network Policies
  6. Regular security updates
  7. Database backups
  8. Monitor logs

Additional Resources


Support

Need help?