cmc-sales/DEPLOYMENT.md

362 lines
8.4 KiB
Markdown
Raw Normal View History

2025-08-04 14:50:12 -07:00
# 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
2025-08-07 18:24:48 -07:00
cd /home/cmc
git clone git@code.springupsoftware.com:cmc/cmc-sales.git cmc-sales
2025-08-04 14:50:12 -07:00
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
2025-08-07 18:24:48 -07:00
# Edit with actual passwords -- up to this.
2025-08-04 14:50:12 -07:00
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
2025-08-07 18:24:48 -07:00
./scripts/setup-lego-certs.sh accounts@springupsoftware.com
2025-08-04 14:50:12 -07:00
# 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
2025-08-07 18:24:48 -07:00
# Wait for services to be ready
sleep 10
2025-08-04 14:50:12 -07:00
# Start reverse proxy (after both environments are running)
docker compose -f docker-compose.proxy.yml up -d
2025-08-07 18:24:48 -07:00
# Or use the make command for full stack deployment
make full-stack
2025-08-04 14:50:12 -07:00
```
### 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