Skip to main content

CivStart Environment Setup Guide

This guide covers the setup and management of Development, Staging, and Production environments for the CivStart project.

Table of Contents

  1. Environment Overview
  2. Environment Configuration
  3. Development Environment
  4. Staging Environment
  5. Production Environment
  6. Database Migrations
  7. Troubleshooting
  8. Best Practices

Environment Overview

CivStart supports three environments:

EnvironmentPurposeBranchDatabase PortBackend PortAdmin PortRedis Port
DevelopmentLocal developmentany5433380038026380
StagingPre-production testingdevelop5434310031026381
ProductionLive applicationmain5432320030026379

Architecture

  • Frontend & Admin: Deployed to Vercel (auto-deploys from git branches)
  • Backend: Dockerized NestJS API
  • Database: PostgreSQL 16 with Prisma ORM
  • Cache: Redis 7
  • Auth: Clerk (separate keys per environment)

Environment Configuration

1. Set Up Environment Files

Each environment requires its own .env file:

# Create from template
cp .env.template .env # Development
cp .env.template .env.staging # Staging
cp .env.template .env.production # Production

Then customize each file with environment-specific values (see .env.template for all options).

For local development, this monorepo uses symlinks so all apps read from a single .env file:

CivStart/
├── .env # ← Root .env (development)
├── apps/
│ ├── frontend/
│ │ └── .env.local # ← Symlink to ../../.env
│ ├── admin/
│ │ └── .env.local # ← Symlink to ../../.env
│ └── backend/
│ └── .env.local # ← Symlink to ../../.env

Create symlinks:

# Automatic (recommended)
pnpm setup

# Or manually
./scripts/setup-env-symlinks.sh

Why symlinks?

  • ✅ Single source of truth for environment variables
  • ✅ No duplicate .env files across apps
  • ✅ Automatic loading by Next.js and NestJS
  • ✅ Works with all dev commands

3. Configure Environment Variables

Development (.env)

NODE_ENV=development
DATABASE_URL="postgresql://civstart:civstart_dev_password@localhost:5433/civstart_dev"
REDIS_URL="redis://localhost:6380"
CLERK_SECRET_KEY=sk_test_YOUR_DEV_KEY

Staging (.env.staging)

NODE_ENV=staging
DATABASE_URL="postgresql://civstart:YOUR_STAGING_PASSWORD@localhost:5434/civstart_staging"
REDIS_URL="redis://localhost:6381"
CLERK_SECRET_KEY=sk_test_YOUR_STAGING_KEY
NEXT_PUBLIC_API_URL=https://api-staging.civstart.ventures

Production (.env.production)

NODE_ENV=production
DATABASE_URL="postgresql://civstart:YOUR_STRONG_PASSWORD@localhost:5432/civstart_production"
REDIS_URL="redis://localhost:6379"
CLERK_SECRET_KEY=sk_live_YOUR_PRODUCTION_KEY
NEXT_PUBLIC_API_URL=https://api.civstart.ventures

Important: Never commit real credentials to version control!

4. Gitignore Configuration

Ensure these patterns are in .gitignore:

.env
.env.local
.env.staging
.env.production
apps/*/.env.local

Development Environment

Initial Setup

# Run the complete setup script
pnpm setup

# Or manually:
pnpm install
pnpm db:generate
pnpm docker:dev:up
pnpm db:migrate

Start Development Services

# Start database and Redis only
pnpm docker:dev:db

# Or start all dev services including pgAdmin
pnpm docker:dev:up

# Start application in watch mode
pnpm dev

# Or start specific apps
pnpm dev:frontend # Port 3801
pnpm dev:backend # Port 3800
pnpm dev:admin # Port 3802

Development Commands

# Database operations
pnpm db:generate # Generate Prisma client
pnpm db:push # Push schema changes
pnpm db:migrate # Run migrations
pnpm db:studio # Open Prisma Studio

# Docker operations
pnpm docker:dev:logs # View all logs
pnpm docker:dev:down # Stop services
pnpm docker:shell:db # PostgreSQL shell

# Testing
pnpm test # Run all tests
pnpm test:coverage # Run with coverage
pnpm validate # Full validation suite

Access Development Services


Staging Environment

Staging is a production-like environment for testing before deployment.

Initial Setup

  1. Create staging environment file:

    cp .env.staging.example .env.staging
  2. Configure Clerk for staging:

  3. Update staging URLs in .env.staging:

    NEXT_PUBLIC_API_URL=https://api-staging.civstart.ventures
    NEXT_PUBLIC_APP_URL=https://staging.civstart.ventures

Start Staging Environment

# Build and start staging services
pnpm docker:staging:build
pnpm docker:staging:up

# Run database migrations
pnpm docker:staging:migrate

# View logs
pnpm docker:staging:logs

Staging Commands

# Container management
pnpm docker:staging:up # Start all staging services
pnpm docker:staging:down # Stop staging services
pnpm docker:staging:restart # Restart services
pnpm docker:staging:rebuild # Rebuild from scratch

# Logs and debugging
pnpm docker:staging:logs # All logs
pnpm docker:staging:logs:backend # Backend only
pnpm docker:staging:logs:admin # Admin only
pnpm docker:staging:logs:db # Database only

# Database access
pnpm docker:staging:shell:db # PostgreSQL shell
pnpm docker:staging:shell:backend # Backend container shell

# Cleanup
pnpm docker:staging:clean # Remove all staging containers and volumes

Staging Port Mapping

  • PostgreSQL: localhost:5434postgres-staging:5432
  • Redis: localhost:6381redis-staging:6379
  • Backend API: localhost:3100backend-staging:3000
  • Admin Panel: localhost:3102admin-staging:3002

Configure Vercel for Staging

  1. Set up staging deployment:

    • Go to Vercel dashboard
    • Add your repository
    • Configure preview deployments from develop branch
  2. Set environment variables in Vercel:

    NEXT_PUBLIC_APP_ENV=staging
    NEXT_PUBLIC_API_URL=https://api-staging.civstart.ventures
    CLERK_SECRET_KEY=sk_test_...
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...

Production Environment

Production is the live environment serving real users.

Prerequisites

  • Production server with Docker installed
  • Domain configured with DNS pointing to server
  • SSL certificates (Let's Encrypt recommended)
  • Backup system configured
  • Monitoring and alerting setup

Initial Setup

  1. Create production environment file:

    cp .env.production.example .env.production
  2. Configure production credentials:

    • Use strong, unique passwords for database
    • Use LIVE Clerk keys (sklive..., pklive...)
    • Set production API keys for all services
    • Configure production domain URLs
  3. Set up SSL/TLS (recommended: nginx reverse proxy with Let's Encrypt)

Deploy Production Environment

# Build production images
pnpm docker:production:build

# Start production services
pnpm docker:production:up

# Run database migrations
pnpm docker:production:migrate

# Verify health
curl http://localhost:3200/health

Production Commands

# Container management
pnpm docker:production:up # Start production services
pnpm docker:production:down # Stop production services
pnpm docker:production:restart # Restart services
pnpm docker:production:rebuild # Rebuild from scratch

# Logs and monitoring
pnpm docker:production:logs # All logs
pnpm docker:production:logs:backend # Backend only
pnpm docker:production:logs:admin # Admin only
pnpm docker:production:logs:db # Database only

# Database access (use with caution!)
pnpm docker:production:shell:db # PostgreSQL shell
pnpm docker:production:shell:backend # Backend container shell

# Backup and maintenance
pnpm docker:production:backup # Create backup

Production Port Mapping

  • PostgreSQL: localhost:5432postgres-production:5432
  • Redis: localhost:6379redis-production:6379
  • Backend API: localhost:3200backend-production:3000
  • Admin Panel: localhost:3002admin-production:3002

Configure Vercel for Production

  1. Set up production deployment:

    • Configure production deployments from main branch
    • Enable automatic deployments
  2. Set production environment variables in Vercel:

    NEXT_PUBLIC_APP_ENV=production
    NEXT_PUBLIC_API_URL=https://api.civstart.ventures
    CLERK_SECRET_KEY=sk_live_...
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_...

Production Monitoring

The production Docker Compose includes:

  • Health checks on all services (30s intervals)
  • Restart policies (unless-stopped)
  • Resource limits (2 CPU, 2GB RAM for backend)
  • Optimized PostgreSQL settings for production workload

Monitor these metrics:

  • Container health: docker ps --format "table {{.Names}}\t{{.Status}}"
  • Resource usage: docker stats
  • Database connections: Check PostgreSQL logs
  • API response times: Backend /health endpoint

Database Migrations

Development Migrations

# Generate migration from schema changes
pnpm db:migrate

# Or use Docker
pnpm docker:migrate

Staging Migrations

# Run migrations in staging
pnpm docker:staging:migrate

# Verify migration
pnpm docker:staging:shell:db
# Then: SELECT * FROM _prisma_migrations;

Production Migrations

⚠️ Important: Always test migrations in staging first!

# 1. Backup production database first
pnpm docker:production:backup

# 2. Run migration
pnpm docker:production:migrate

# 3. Verify migration success
pnpm docker:production:shell:db
# Then: SELECT * FROM _prisma_migrations ORDER BY finished_at DESC LIMIT 5;

# 4. Test application functionality
curl http://localhost:3000/health

Migration Best Practices

  1. Always backup before migrating production
  2. Test migrations in staging first
  3. Review migration SQL before running
  4. Have rollback plan ready
  5. Monitor application after migration
  6. Use Prisma's migrate commands (not manual SQL)

Troubleshooting

Common Issues

Port Already in Use

# Check what's using the port
lsof -i :5432 # or :5433, :5434

# Kill the process
kill -9 <PID>

# Or use the helper script
./scripts/ensure-ports-free.sh

Database Connection Failed

# Check if PostgreSQL is running
docker ps | grep postgres

# Check logs
pnpm docker:dev:logs:db # Development
pnpm docker:staging:logs:db # Staging
pnpm docker:production:logs:db # Production

# Restart database
docker restart civstart-postgres-dev

Prisma Client Out of Sync

# Regenerate Prisma client
pnpm db:generate

# If using Docker, also regenerate in container
pnpm docker:staging:build

Migration Failed

# Check migration status
pnpm docker:staging:shell:db
SELECT * FROM _prisma_migrations WHERE success = false;

# Roll back if needed (staging only)
# Manually revert in production with extreme caution

Container Won't Start

# Check container logs
docker logs civstart-backend-staging

# Remove and recreate
pnpm docker:staging:down
pnpm docker:staging:clean
pnpm docker:staging:build
pnpm docker:staging:up

Environment Variables Not Loading (Development)

If environment variables aren't loading in development:

# 1. Check symlinks exist
ls -la apps/frontend/.env.local
ls -la apps/admin/.env.local
ls -la apps/backend/.env.local

# 2. Recreate symlinks if missing
./scripts/setup-env-symlinks.sh

# 3. Verify root .env file exists and has values
cat .env

# 4. Clear Next.js cache
rm -rf apps/frontend/.next apps/admin/.next

# 5. Restart dev server
pnpm dev

Health Checks

# Check all services are healthy
docker ps --format "table {{.Names}}\t{{.Status}}"

# Test backend health endpoint
curl http://localhost:3800/health # Dev
curl http://localhost:3100/health # Staging
curl http://localhost:3200/health # Production

# Test Redis connection
docker exec civstart-redis-dev redis-cli ping

Best Practices

Environment Isolation

  1. Never use production credentials in dev/staging
  2. Use separate Clerk applications for each environment
  3. Isolate data - don't connect dev to production databases
  4. Test with production-like data in staging, but anonymized

Deployment Workflow

Feature Branch → develop → Staging → main → Production
↓ ↓
Auto-deploy to Auto-deploy to
Staging Vercel Production Vercel
  1. Develop feature on feature branch
  2. Merge to develop → auto-deploys to staging
  3. Test thoroughly in staging
  4. Merge to main → auto-deploys to production
  5. Monitor production for issues

Security Checklist

  • Strong, unique passwords for all production services
  • SSL/TLS enabled for all public endpoints
  • Firewall configured (only necessary ports open)
  • Regular security updates for Docker images
  • Secrets stored securely (never in git)
  • Rate limiting configured
  • CORS properly configured
  • Audit logs enabled

Backup Strategy

  1. Automated daily backups of production database
  2. Retention policy: 30 days minimum
  3. Test restores regularly (monthly)
  4. Store backups off-site (different provider)
  5. Backup before deployments
  6. Document restore procedures

Monitoring

Recommended monitoring tools:

  • Application: Sentry for error tracking
  • Uptime: UptimeRobot or similar
  • Logs: CloudWatch, Papertrail, or similar
  • Metrics: Grafana + Prometheus
  • Database: pgAdmin, DataDog

Set up alerts for:

  • Service downtime
  • High error rates
  • Database connection pool exhaustion
  • High memory/CPU usage
  • Failed deployments

Quick Reference

Environment Commands Cheat Sheet

# Development
pnpm docker:dev:up && pnpm dev

# Staging
pnpm docker:staging:up
pnpm docker:staging:logs

# Production
pnpm docker:production:up
pnpm docker:production:logs

# All environments: check health
curl http://localhost:3800/health # Dev
curl http://localhost:3100/health # Staging
curl http://localhost:3200/health # Production

Port Reference

ServiceDevStagingProduction
PostgreSQL543354345432
Redis638063816379
Backend380031003200
Admin380231023002
Frontend3801VercelVercel

Getting Help

  • Getting Started: See README.md for quick start and installation
  • Architecture: See ARCHITECTURE.md for system design and structure
  • Deployment: See DEPLOYMENT.md for CI/CD and PM2 setup
  • Testing: See TEST-CREDENTIALS.md for test environment setup
  • Database: Check packages/database/README.md
  • Issues: Report bugs at GitHub Issues

Last Updated: 2025-10-23