# 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) ```bash # 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 ```bash cd /home/cmc git clone git@code.springupsoftware.com:cmc/cmc-sales.git cmc-sales sudo chown -R $USER:$USER cmc-sales cd cmc-sales ``` ### 2. Environment Configuration ```bash # Copy environment files cp .env.staging go-app/.env.staging cp .env.production go-app/.env.production # Edit with actual passwords -- up to this. 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](https://console.cloud.google.com) 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): ```bash cd go-app go run cmd/auth/main.go # Follow OAuth flow # Copy token.json to appropriate credential directory ``` ### 4. SSL Certificates ```bash # 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 accounts@springupsoftware.com # Verify certificates ./scripts/lego-list-certs.sh ``` ### 5. Database Initialization ```bash # 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 ```bash # Start staging environment docker compose -f docker-compose.staging.yml up -d # Start production environment docker compose -f docker-compose.production.yml up -d # Wait for services to be ready sleep 10 # Start reverse proxy (after both environments are running) docker compose -f docker-compose.proxy.yml up -d # Or use the make command for full stack deployment make full-stack ``` ### Updating Applications ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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: ```bash # 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** ```bash # Check logs docker compose logs container-name # Check system resources df -h free -h ``` 2. **SSL issues** ```bash # 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** ```bash # Test database connectivity docker exec -it cmc-db-production mysql -u cmc -p ``` 4. **Gmail API issues** ```bash # 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** ```bash # 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** ```bash # 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 ```sql -- 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