CivStart Deployment Guide
This guide explains the CivStart deployment architecture and how deployments are managed.
Table of Contents
- Architecture Overview
- CI Pipeline (GitHub Actions)
- Backend Deployment (CloudFormation/AWS)
- Frontend & Admin Deployment (Vercel)
- Tracking Deployments on GitHub
- Manual Deployment
- Configuration
- Troubleshooting
- Rollback Procedures
Architecture Overview
CivStart uses a separation of concerns approach for CI/CD:
🔍 CI Pipeline (GitHub Actions)
- Purpose: Quality gates before merging code
- Runs on: Every push and pull request
- Includes:
- Code quality checks (linting, type checking, formatting)
- Test suite with coverage
- Build verification
- Database migration validation
- Docker build verification
- Security scans
🚀 Deployment (External Systems)
- Backend: CloudFormation/AWS handles deployment and infrastructure
- Frontend & Admin: Vercel handles automatic deployment
- Separation: Deployments happen outside GitHub Actions
📊 Deployment Tracking
- See DEPLOYMENT-TRACKING.md for how to track CloudFormation and Vercel deployments on GitHub
CI Pipeline (GitHub Actions)
Workflow: .github/workflows/ci.yml
The CI pipeline runs automatically on:
- Pushes to
main,develop,dev,stagingbranches - Pull requests to these branches
Jobs
- Code Quality - Linting, type checking, formatting
- Test Suite - Unit tests with PostgreSQL and Redis
- Build Verification - Backend build validation
- Migration Validation - Prisma migration checks
- Docker Build - Backend Docker image verification
- Security Scan - Dependency audits and Trivy scans
Purpose
The CI pipeline acts as a quality gate - it ensures code meets standards before merging, but does not deploy the application.
Backend Deployment (CloudFormation/AWS)
Deployment Method
Backend services are deployed via AWS CloudFormation, which:
- Provisions infrastructure (ECS, RDS, ElastiCache, etc.)
- Builds and deploys Docker containers
- Manages database migrations
- Handles health checks and rollbacks
Triggering Deployments
Deployments are triggered outside GitHub Actions, typically:
- Via AWS CodePipeline (automatic on code changes)
- Via CloudFormation CLI (manual)
- Via AWS Console (manual)
Deployment Architecture
Code Merge → CloudFormation Stack Update
├─ Build Docker image (backend)
├─ Push to ECR
├─ Update ECS task definition
├─ Run database migrations
└─ Deploy to ECS cluster
Manual Deployment
# Deploy backend to staging
aws cloudformation deploy \
--template-file infrastructure/backend.yaml \
--stack-name civstart-backend-staging \
--parameter-overrides Environment=staging \
--capabilities CAPABILITY_IAM
# Deploy backend to production
aws cloudformation deploy \
--template-file infrastructure/backend.yaml \
--stack-name civstart-backend-production \
--parameter-overrides Environment=production \
--capabilities CAPABILITY_IAM
Frontend & Admin Deployment (Vercel)
Deployment Method
Frontend and Admin applications are deployed via Vercel, which:
- Automatically builds on git push
- Deploys to global CDN
- Provides preview URLs for PRs
- Handles automatic rollbacks
Automatic Deployment
Production deployments (triggered automatically):
- Push to
mainbranch → Vercel deploys to production - Production URLs:
- Frontend: https://civstart.com
- Admin: https://admin.civstart.com
Preview deployments (triggered automatically):
- Every commit on a PR → Vercel creates preview URL
- Preview URLs: https://civstart-frontend-git-{branch}.vercel.app
Vercel Configuration
Each app has a vercel.json configuration:
Frontend (apps/frontend/vercel.json):
{
"github": {
"enabled": true,
"silent": false
},
"buildCommand": "cd ../.. && pnpm run build --filter=@civstart/frontend",
"installCommand": "cd ../.. && pnpm install"
}
Admin (apps/admin/vercel.json):
{
"github": {
"enabled": true,
"silent": false
},
"buildCommand": "cd ../.. && pnpm run build --filter=@civstart/admin",
"installCommand": "cd ../.. && pnpm install"
}
Manual Deployment (if needed)
# Install Vercel CLI
pnpm add -g vercel
# Deploy frontend to production
cd apps/frontend
vercel --prod
# Deploy admin to production
cd apps/admin
vercel --prod
Tracking Deployments on GitHub
To see deployment status directly on GitHub PRs and commits, see the comprehensive guide:
This guide covers:
- ✅ Automatic Vercel deployment tracking (already enabled)
- 🔧 CloudFormation deployment reporting via GitHub API
- 📊 Viewing deployment history and status
Manual Deployment (Legacy)
Note: This section describes the legacy manual deployment process. Current deployments are handled by CloudFormation (backend) and Vercel (frontend/admin).
Initial Setup
1. Configure GitHub Secrets (Legacy)
Add the following secrets to your GitHub repository:
Go to: Settings → Secrets and variables → Actions → New repository secret
| Secret Name | Description | Example |
|---|---|---|
PRODUCTION_SSH_KEY | Private SSH key for deployment | -----BEGIN OPENSSH PRIVATE KEY---- |
PRODUCTION_HOST | Production server hostname or IP | your-server.com or 192.168.1.100 |
PRODUCTION_USER | SSH username for deployment | deploy or ubuntu |
PRODUCTION_PATH | Absolute path to CivStart project on server | /home/deploy/civstart |
2. Generate SSH Key Pair
On your local machine or CI server:
# Generate a new SSH key pair for deployment
ssh-keygen -t ed25519 -C "civstart-deploy" -f ~/.ssh/civstart_deploy_key
# Display the private key (add this to GitHub Secrets)
cat ~/.ssh/civstart_deploy_key
# Display the public key (add this to server's authorized_keys)
cat ~/.ssh/civstart_deploy_key.pub
3. Configure Production Server
On your production server:
# Add the public key to authorized_keys
echo "YOUR_PUBLIC_KEY_HERE" >> ~/.ssh/authorized_keys
# Set correct permissions
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
# Make deployment script executable
cd /path/to/civstart
chmod +x scripts/deploy-production.sh
4. Configure PM2 for Backend (First Time Setup)
Note: PM2 is only used for the backend service. Frontend and Admin are deployed via Vercel (see below).
If you haven't set up PM2 yet, create an ecosystem.config.js in your project root:
module.exports = {
apps: [
{
name: "civstart-backend",
cwd: "/path/to/civstart/apps/backend",
script: "dist/main.js",
instances: 1,
exec_mode: "fork",
env: {
NODE_ENV: "production",
PORT: 3800,
},
},
],
};
Start PM2 process:
pm2 start ecosystem.config.js
pm2 save
pm2 startup # Follow instructions to enable PM2 on system boot
Deploy to Production
Backend Deployment (Automated)
Simply push to the main branch:
git push origin main
GitHub Actions will automatically:
- Run code quality checks (linting, type checking, formatting)
- Run test suite with coverage
- Build and verify backend application
- Build Docker image for backend
- SSH to production server
- Execute deployment script for backend
- Restart backend service (Docker or PM2)
- Run health checks
- Notify on success or failure
Note: Frontend and Admin are NOT deployed via GitHub Actions. They are automatically deployed by Vercel when changes are pushed to main.
Frontend & Admin Deployment (Vercel)
Frontend and Admin are automatically deployed by Vercel when you push to main. No additional configuration needed.
Monitor Deployment
View deployment progress:
- Go to GitHub → Actions
- Click on the latest workflow run
- Watch the "Deploy to Production" job
Manual Deployment
If you need to deploy manually (for testing or emergency deployments):
1. SSH to Production Server
ssh user@your-production-server.com
cd /path/to/civstart
2. Run Deployment Script
Standard deployment:
./scripts/deploy-production.sh
Skip tests (faster, use with caution):
./scripts/deploy-production.sh --skip-tests
Skip backup creation:
./scripts/deploy-production.sh --no-backup
3. Verify Deployment
Check PM2 backend status:
pm2 status
pm2 logs civstart-backend --lines 50
Test backend health endpoint:
curl http://localhost:3800/health
Frontend and Admin verification:
- Frontend: Check your Vercel dashboard or visit your production URL
- Admin: Check your Vercel dashboard or visit your admin production URL
Configuration
Environment Variables
Ensure the following environment variables are set on your production server:
Backend Server (Required):
DATABASE_URL- PostgreSQL connection stringCLERK_SECRET_KEY- Clerk authentication secretPORT- Backend port (default: 3800)NODE_ENV- Environment (production)
Backend Server (Optional):
BACKEND_URL- Override backend URL for health checks (default:http://localhost:3800)REDIS_URL- Redis connection string (if using Redis)PINECONE_API_KEY- For vector search featuresGOOGLE_GEMINI_API_KEY- For AI featuresAIRTABLE_API_KEY- For Airtable integration
Vercel (Frontend/Admin):
NEXT_PUBLIC_API_URL- Backend API URL (your production backend URL)NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY- Clerk public keyCLERK_SECRET_KEY- Clerk secret key
Set these in your Vercel project settings under Environment Variables.
Deployment Script Options
Customize the deployment script by editing scripts/deploy-production.sh:
# PM2 Process Name (backend only)
readonly PM2_BACKEND="civstart-backend"
# Health Check Configuration
readonly HEALTH_CHECK_RETRIES=5
readonly HEALTH_CHECK_INTERVAL=10
Note: Frontend and Admin are not managed by this script as they are deployed on Vercel.
Troubleshooting
Deployment Fails During Build
Symptoms: Build step fails with errors
Solutions:
- Check Node.js version compatibility (requires Node 18+)
- Ensure all dependencies are installed:
pnpm install - Check for TypeScript errors:
pnpm typecheck - Verify Prisma schema is valid:
pnpm db:generate
PM2 Processes Won't Restart
Symptoms: PM2 restart command fails
Solutions:
# Check PM2 process status
pm2 list
# View PM2 logs for errors
pm2 logs civstart-backend --err --lines 100
# Delete and recreate process
pm2 delete civstart-backend
pm2 start ecosystem.config.js --only civstart-backend
pm2 save
Health Checks Fail
Symptoms: Deployment rolls back due to failed health checks
Solutions:
-
Verify application is listening on correct port:
netstat -tlnp | grep 3800 # Check backend port -
Check application logs:
pm2 logs civstart-backend --lines 100 -
Test health endpoint manually:
curl -v http://localhost:3800/health -
Ensure database is accessible:
psql "$DATABASE_URL" -c "SELECT 1"
Database Migration Errors
Symptoms: Migration step fails
Solutions:
# Check database connection
pnpm --filter=@repo/database db:pull
# View migration status
pnpm --filter=@repo/database prisma migrate status
# Force push schema (development only!)
pnpm db:push --accept-data-loss
SSH Connection Issues
Symptoms: GitHub Actions can't SSH to server
Solutions:
-
Verify SSH key in GitHub Secrets matches server's
authorized_keys -
Test SSH connection manually:
ssh -i ~/.ssh/deploy_key user@server -
Check server SSH logs:
sudo tail -f /var/log/auth.log # Ubuntu/Debian
sudo tail -f /var/log/secure # CentOS/RHEL -
Verify firewall allows SSH (port 22)
Rollback Procedures
Automatic Rollback
The deployment script automatically creates backup tags and rolls back on failure.
Manual Rollback
If you need to manually rollback to a previous version:
1. Find Backup Tag
# List recent backup tags
git tag -l "backup-*" --sort=-creatordate | head -n 10
2. Checkout Backup
# Rollback to specific backup
git checkout backup-20250121-143022
# Or rollback to previous commit
git checkout HEAD~1
3. Redeploy
./scripts/deploy-production.sh
Emergency Rollback (Fast)
For critical issues, use the last backup tag:
# Find last backup
LAST_BACKUP=$(git tag -l "backup-*" --sort=-creatordate | head -n 1)
# Rollback
git checkout $LAST_BACKUP
pnpm install --frozen-lockfile
pnpm db:generate
pnpm build
pm2 restart all
Best Practices
Before Deploying
- Run tests locally:
pnpm test - Check TypeScript types:
pnpm typecheck - Run linter:
pnpm lint - Test build locally:
pnpm build - Review database migrations
- Update changelog/version if needed
After Deploying
- Monitor PM2 logs:
pm2 logs --lines 100 - Check application health endpoints
- Verify critical user flows
- Monitor error tracking (if configured)
- Check database performance
Production Checklist
- Environment variables are set
- Database backups are automated
- SSL/TLS certificates are valid
- Firewall rules are configured
- PM2 is configured for auto-restart
- Monitoring/alerting is set up
- Log rotation is configured
Additional Resources
Support
For deployment issues:
- Check PM2 logs:
pm2 logs civstart-backend - Review GitHub Actions logs in the Actions tab
- Check server system logs:
journalctl -u pm2-* - Verify environment variables are set correctly
For critical production issues, follow the Emergency Rollback procedure first, then investigate.