DEPLOYMENT.md 12 KB

Production Deployment Guide

Overview

This guide walks you through deploying the SaaS Platform on a production server with automatic SSL certificate generation using Let's Encrypt.

Prerequisites

Server Requirements

  • OS: Ubuntu 20.04+ / Debian 11+ / CentOS 8+ / RHEL 8+
  • RAM: Minimum 4GB (8GB+ recommended)
  • CPU: 2+ cores recommended
  • Storage: 20GB+ available disk space
  • Network: Public IP address with ports 80 and 443 accessible

Domain Requirements

You must have a domain with the following DNS records configured:

Record Type Name Value Purpose
A example.com your-server-ip Main domain
A console.example.com your-server-ip Dashboard/Console
A *.example.com your-server-ip Wildcard for apps

Important: All three DNS records are required before running the deployment script.

Verify DNS Configuration

# Check main domain
dig +short A example.com

# Check console subdomain
dig +short A console.example.com

# Check wildcard (test with any subdomain)
dig +short A test.example.com

All three should return your server's IP address.


Quick Start

1. Clone the Repository

# SSH into your server
ssh user@your-server-ip

# Clone the repository
git clone https://github.com/yourusername/saas-platform.git
cd saas-platform

2. Run the Deployment Script

chmod +x deploy.sh
./deploy.sh

3. Follow the Prompts

The script will ask for:

  1. Domain Name: Enter your domain (e.g., example.com)

    • Script validates DNS records automatically
    • Checks for A records and wildcard support
  2. Email Address: Enter your email for Let's Encrypt

    • Used for certificate expiration notifications
    • Required by Let's Encrypt
  3. Confirmation: Review and confirm deployment

4. Wait for Deployment

The script will:

  • ✅ Validate DNS records
  • ✅ Install Certbot (if not installed)
  • ✅ Generate Let's Encrypt SSL certificates
  • ✅ Configure Nginx with SSL/TLS
  • ✅ Create environment file with random secrets
  • ✅ Deploy hello world application
  • ✅ Start all Docker services
  • ✅ Setup automatic certificate renewal

Deployment time: ~5-10 minutes


What Gets Deployed

Services

Service Port Description
Nginx 80, 443 API Gateway, SSL termination
PostgreSQL 5432 Primary database
Redis 6379 Caching and pub/sub
Auth Service 3001 Authentication API
API Service 3000 Core business logic
Realtime Service 3002 WebSocket server
Dashboard 5173 React admin UI
MinIO 9000, 9001 S3-compatible storage
Prometheus 9090 Metrics collection
Grafana 3003 Monitoring dashboards

URLs

After deployment, the following URLs will be available:

  • Main Site: https://example.com (Hello World app)
  • Dashboard: https://console.example.com
  • API: https://console.example.com/api
  • WebSocket: wss://console.example.com/ws
  • Health Check: https://console.example.com/health

Files Created

/data/appserver/
├── .env                    # Environment configuration (KEEP SECURE!)
├── ssl/
│   ├── certificate.crt     # SSL certificate (Let's Encrypt)
│   ├── private.key         # Private key (KEEP SECURE!)
│   └── dhparam.pem         # DH parameters
├── nginx/conf.d/
│   └── production.conf     # Production Nginx config
├── apps/
│   └── hello-world/        # Hello World application
│       └── index.html
└── renew-certs.sh          # Certificate renewal script

Post-Deployment Steps

1. Access the Dashboard

  1. Visit https://console.yourdomain.com
  2. You may see a brief loading screen on first visit
  3. Create your admin account:
    • Email: admin@yourdomain.com
    • Password: Choose a strong password

2. Verify Hello World App

Visit https://yourdomain.com to see the hello world application.

3. Check Service Health

# Check all services are running
docker-compose ps

# Check specific service logs
docker-compose logs -f api-service
docker-compose logs -f auth-service
docker-compose logs -f nginx

# Check API health
curl https://console.yourdomain.com/api/health

4. Configure Monitoring (Optional)

Access Grafana at http://your-server-ip:3003

  • Default credentials: admin / admin
  • Change password on first login
  • Pre-configured dashboards available

Security Recommendations

1. Secure the .env File

# The .env file contains sensitive passwords
chmod 600 .env

# Never commit .env to version control
git add .env  # DON'T DO THIS!

2. Update Default Passwords

The deployment script generates random passwords, but you should:

  1. Database Backup User: Create a separate read-only backup user
  2. Grafana: Change the default admin password
  3. pgAdmin: Set a master password on first use

3. Enable Firewall

# Ubuntu/Debian
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp  # SSH
sudo ufw enable

# CentOS/RHEL
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

4. Setup Backups

# Create backup script
cat > backup.sh <<'EOF'
#!/bin/bash
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)

# Backup database
docker exec saas-postgres pg_dump -U saas_user saas_platform > "$BACKUP_DIR/db_$DATE.sql"

# Backup .env and configs
tar -czf "$BACKUP_DIR/config_$DATE.tar.gz" .env nginx/ ssl/

# Keep only last 7 days
find "$BACKUP_DIR" -name "*.sql" -mtime +7 -delete
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
EOF

chmod +x backup.sh

# Add to crontab (daily at 2 AM)
(crontab -l 2>/dev/null; echo "0 2 * * * /data/appserver/backup.sh") | crontab -

5. Monitor Certificate Expiration

Certificates auto-renew, but verify:

# Check certificate expiration
openssl x509 -in ssl/certificate.crt -noout -dates

# Test renewal (dry run)
sudo certbot renew --dry-run

SSL/TLS Certificate Management

Automatic Renewal

The deployment script configures automatic renewal via cron:

  • Frequency: Twice daily (12 AM and 12 PM)
  • Script: renew-certs.sh
  • Logs: logs/cert-renewal.log

Manual Renewal

# Stop Nginx to free port 80
docker stop saas-gateway

# Renew certificate
sudo certbot renew

# Copy renewed certificates
sudo cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem ssl/certificate.crt
sudo cp /etc/letsencrypt/live/yourdomain.com/privkey.pem ssl/private.key

# Start Nginx
docker start saas-gateway
docker exec saas-gateway nginx -s reload

Check Renewal Status

# View renewal logs
cat logs/cert-renewal.log

# List all certificates
sudo certbot certificates

Troubleshooting

DNS Records Not Propagating

Issue: Script reports DNS records not found

Solutions:

  1. Wait 5-60 minutes for DNS propagation
  2. Verify records in your DNS provider's dashboard
  3. Use dig @8.8.8.8 yourdomain.com to check Google's DNS
  4. Clear local DNS cache: sudo systemd-resolve --flush-caches

Certificate Generation Failed

Issue: Let's Encrypt certificate request fails

Common Causes:

  1. Port 80 blocked: Ensure firewall allows port 80
  2. Wrong IP: DNS points to different IP than server
  3. Rate limit: Let's Encrypt has rate limits (5 per week)

Solutions:

# Check if port 80 is accessible
curl -I http://yourdomain.com

# Verify DNS points to this server
dig +short A yourdomain.com

# Check Let's Encrypt rate limits
# Wait 1 week or use staging server for testing

Services Not Starting

Issue: Docker containers fail to start

Solutions:

# Check Docker daemon
sudo systemctl status docker

# View container logs
docker-compose logs

# Rebuild and restart
docker-compose down
docker-compose up -d --build

# Check system resources
free -h  # Memory
df -h    # Disk space

Cannot Access Dashboard

Issue: https://console.yourdomain.com not accessible

Solutions:

  1. Check DNS: dig +short console.yourdomain.com
  2. Check Nginx: docker logs saas-gateway
  3. Check certificate: curl -vI https://console.yourdomain.com
  4. Check firewall: sudo ufw status

Database Connection Errors

Issue: Services cannot connect to database

Solutions:

# Check PostgreSQL is running
docker exec saas-postgres pg_isready

# Check database credentials in .env
cat .env | grep POSTGRES

# View database logs
docker logs saas-postgres

# Connect to database manually
docker exec -it saas-postgres psql -U saas_user -d saas_platform

Updating the Platform

Pull Latest Changes

cd /data/appserver
git pull origin main

Rebuild Services

# Stop services
docker-compose down

# Rebuild
docker-compose build

# Start services
docker-compose up -d

Database Migrations

# Backup database first!
./backup.sh

# Run migrations (if any)
docker exec saas-api npm run migrate

# Or restore from backup if needed
cat backups/db_YYYYMMDD_HHMMSS.sql | docker exec -i saas-postgres psql -U saas_user -d saas_platform

Monitoring and Logs

View All Service Logs

# All services
docker-compose logs -f

# Specific service
docker-compose logs -f api-service

# Last 100 lines
docker-compose logs --tail=100 api-service

Check Service Health

# All services status
docker-compose ps

# Specific service health
curl https://console.yourdomain.com/api/health
curl https://console.yourdomain.com/auth/health

# Database connection
docker exec saas-postgres pg_isready

Monitor Resources

# Container resource usage
docker stats

# System resources
htop  # Install: sudo apt install htop

Access Monitoring Dashboards

  • Grafana: http://your-server-ip:3003
  • Prometheus: http://your-server-ip:9090
  • pgAdmin: http://your-server-ip:5050

Scaling Considerations

Vertical Scaling

Increase server resources:

  • Upgrade to a larger VM/instance
  • Add more RAM and CPU cores
  • Use SSD storage for database

Horizontal Scaling

For high traffic:

  1. Load Balancer: Add multiple API/Auth service replicas
  2. Database: Setup PostgreSQL replication
  3. Redis: Use Redis Cluster
  4. Storage: External S3 instead of MinIO

Database Optimization

# Increase PostgreSQL connections (in docker-compose.yml)
environment:
  POSTGRES_MAX_CONNECTIONS: 200

# Add database indexes
docker exec -it saas-postgres psql -U saas_user -d saas_platform
CREATE INDEX idx_users_email ON __sys_users(email);

Uninstalling

Stop and Remove All Services

# Stop all containers
docker-compose down

# Remove volumes (WARNING: deletes all data!)
docker-compose down -v

# Remove images
docker-compose down --rmi all

# Remove SSL certificates
sudo certbot delete --cert-name yourdomain.com

Clean Up Files

cd /data/appserver
rm -rf postgres_data redis_data minio_data
rm .env

Support and Documentation


Deployment Checklist

Before going to production:

  • DNS records configured (A, console, wildcard)
  • Server meets minimum requirements (4GB RAM, 2 CPU)
  • Firewall configured (ports 80, 443, 22)
  • Domain name verified with dig command
  • Email address ready for Let's Encrypt
  • Backup strategy planned
  • Monitoring dashboards configured
  • SSL certificates auto-renewal tested
  • Database backups scheduled
  • Admin account created
  • Security headers verified
  • Application deployment tested

Generated by the SaaS Platform Deployment Script