cmc-sales/DEPLOYMENT.md
2025-08-05 07:50:12 +10:00

8.2 KiB

CMC Sales Deployment Guide

Overview

This guide covers deploying the CMC Sales application to a Debian 12 VM at cmc.springupsoftware.com with both staging and production environments.

Architecture

  • Production: https://cmc.springupsoftware.com
  • Staging: https://staging.cmc.springupsoftware.com
  • Components: CakePHP legacy app, Go modern app, MariaDB, Nginx reverse proxy
  • SSL: Let's Encrypt certificates
  • Authentication: Basic auth for both environments

Prerequisites

Server Setup (Debian 12)

# Update system
sudo apt update && sudo apt upgrade -y

# Install Docker and Docker Compose
sudo apt install -y docker.io docker-compose-plugin
sudo systemctl enable docker
sudo systemctl start docker

# Add user to docker group
sudo usermod -aG docker $USER
# Log out and back in

# Create backup directory
sudo mkdir -p /var/backups/cmc-sales
sudo chown $USER:$USER /var/backups/cmc-sales

DNS Configuration

Ensure these DNS records point to your server:

  • cmc.springupsoftware.com → Server IP
  • staging.cmc.springupsoftware.com → Server IP

Initial Deployment

1. Clone Repository

cd /opt
sudo git clone <repository-url> cmc-sales
sudo chown -R $USER:$USER cmc-sales
cd cmc-sales

2. Environment Configuration

# Copy environment files
cp .env.staging go-app/.env.staging
cp .env.production go-app/.env.production

# Edit with actual passwords
nano .env.staging
nano .env.production

# Create credential directories
mkdir -p credentials/staging credentials/production

3. Gmail OAuth Setup

For each environment (staging/production):

  1. Go to Google Cloud Console
  2. Create/select project
  3. Enable Gmail API
  4. Create OAuth 2.0 credentials
  5. Download credentials.json
  6. Place in appropriate directory:
    • Staging: credentials/staging/credentials.json
    • Production: credentials/production/credentials.json

Generate tokens (run on local machine first):

cd go-app
go run cmd/auth/main.go
# Follow OAuth flow
# Copy token.json to appropriate credential directory

4. SSL Certificates

# Start proxy services (includes Lego container)
docker compose -f docker-compose.proxy.yml up -d

# Setup SSL certificates using Lego
./scripts/setup-lego-certs.sh admin@springupsoftware.com

# Verify certificates
./scripts/lego-list-certs.sh

5. Database Initialization

# Start database containers first
docker compose -f docker-compose.staging.yml up -d db-staging
docker compose -f docker-compose.production.yml up -d db-production

# Wait for databases to be ready
sleep 30

# Restore production database (if you have a backup)
./scripts/restore-db.sh production /path/to/backup.sql.gz

# Or initialize empty database and run migrations
# (implementation specific)

Deployment Commands

Starting Services

# Start staging environment
docker compose -f docker-compose.staging.yml up -d

# Start production environment  
docker compose -f docker-compose.production.yml up -d

# Start reverse proxy (after both environments are running)
docker compose -f docker-compose.proxy.yml up -d

Updating Applications

# Pull latest code
git pull origin main

# Rebuild and restart staging
docker compose -f docker-compose.staging.yml down
docker compose -f docker-compose.staging.yml build --no-cache
docker compose -f docker-compose.staging.yml up -d

# Test staging thoroughly, then update production
docker compose -f docker-compose.production.yml down
docker compose -f docker-compose.production.yml build --no-cache
docker compose -f docker-compose.production.yml up -d

Monitoring and Maintenance

Health Checks

# Check all containers
docker ps

# Check logs
docker compose -f docker-compose.production.yml logs -f

# Check application health
curl https://cmc.springupsoftware.com/health
curl https://staging.cmc.springupsoftware.com/health

Database Backups

# Manual backup
./scripts/backup-db.sh production
./scripts/backup-db.sh staging

# Set up automated backups (cron)
sudo crontab -e
# Add: 0 2 * * * /opt/cmc-sales/scripts/backup-db.sh production
# Add: 0 3 * * * /opt/cmc-sales/scripts/backup-db.sh staging

Log Management

# View nginx logs
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

# View application logs
docker compose -f docker-compose.production.yml logs -f cmc-go-production
docker compose -f docker-compose.staging.yml logs -f cmc-go-staging

SSL Certificate Renewal

# Manual renewal
./scripts/lego-renew-cert.sh all

# Renew specific domain
./scripts/lego-renew-cert.sh cmc.springupsoftware.com

# Set up auto-renewal (cron)
sudo crontab -e
# Add: 0 2 * * * /opt/cmc-sales/scripts/lego-renew-cert.sh all

Security Considerations

Basic Authentication

Update passwords in userpasswd file:

# Generate new password hash
sudo apt install apache2-utils
htpasswd -c userpasswd username

# Restart nginx containers
docker compose -f docker-compose.proxy.yml restart nginx-proxy

Database Security

  • Use strong passwords in environment files
  • Database containers are not exposed externally in production
  • Regular backups with encryption at rest

Network Security

  • All traffic encrypted with SSL/TLS
  • Rate limiting configured in nginx
  • Security headers enabled
  • Docker networks isolate environments

Troubleshooting

Common Issues

  1. Containers won't start

    # Check logs
    docker compose logs container-name
    
    # Check system resources
    df -h
    free -h
    
  2. SSL issues

    # Check certificate status
    ./scripts/lego-list-certs.sh
    
    # Test SSL configuration
    curl -I https://cmc.springupsoftware.com
    
    # Manually renew certificates
    ./scripts/lego-renew-cert.sh all
    
  3. Database connection issues

    # Test database connectivity
    docker exec -it cmc-db-production mysql -u cmc -p
    
  4. Gmail API issues

    # Check credentials are mounted
    docker exec -it cmc-go-production ls -la /root/credentials/
    
    # Check logs for OAuth errors
    docker compose logs cmc-go-production | grep -i gmail
    

Emergency Procedures

  1. Quick rollback

    # Stop current containers
    docker compose -f docker-compose.production.yml down
    
    # Restore from backup
    ./scripts/restore-db.sh production /var/backups/cmc-sales/latest_backup.sql.gz
    
    # Start previous version
    git checkout previous-commit
    docker compose -f docker-compose.production.yml up -d
    
  2. Database corruption

    # Stop application
    docker compose -f docker-compose.production.yml stop cmc-go-production cmc-php-production
    
    # Restore from backup
    ./scripts/restore-db.sh production /var/backups/cmc-sales/backup_production_YYYYMMDD-HHMMSS.sql.gz
    
    # Restart application
    docker compose -f docker-compose.production.yml start cmc-go-production cmc-php-production
    

File Structure

/opt/cmc-sales/
├── docker-compose.staging.yml
├── docker-compose.production.yml
├── docker-compose.proxy.yml
├── conf/
│   ├── nginx-staging.conf
│   ├── nginx-production.conf
│   └── nginx-proxy.conf
├── credentials/
│   ├── staging/
│   │   ├── credentials.json
│   │   └── token.json
│   └── production/
│       ├── credentials.json
│       └── token.json
├── scripts/
│   ├── backup-db.sh
│   ├── restore-db.sh
│   ├── lego-obtain-cert.sh
│   ├── lego-renew-cert.sh
│   ├── lego-list-certs.sh
│   └── setup-lego-certs.sh
└── .env files

Performance Tuning

Resource Limits

Resource limits are configured in the Docker Compose files:

  • Production: 2 CPU cores, 2-4GB RAM per service
  • Staging: More relaxed limits for testing

Database Optimization

-- Monitor slow queries
SHOW VARIABLES LIKE 'slow_query_log';
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;

-- Check database performance
SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS;

Nginx Optimization

  • Gzip compression enabled
  • Static file caching
  • Connection keep-alive
  • Rate limiting configured