cmc-sales/DEPLOYMENT-CADDY.md

344 lines
8 KiB
Markdown
Raw Normal View History

2025-08-07 18:24:48 -07:00
# CMC Sales Deployment Guide with Caddy
## Overview
This guide covers deploying the CMC Sales application to a Debian 12 VM using Caddy as the reverse proxy with automatic HTTPS.
## Architecture
- **Production**: `https://cmc.springupsoftware.com`
- **Staging**: `https://staging.cmc.springupsoftware.com`
- **Reverse Proxy**: Caddy (running on host)
- **Applications**: Docker containers
- CakePHP legacy app
- Go modern app
- MariaDB database
- **SSL**: Automatic via Caddy (Let's Encrypt)
- **Authentication**: Basic auth configured in Caddy
## Prerequisites
### 1. Server Setup (Debian 12)
```bash
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker
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 directories
sudo mkdir -p /var/backups/cmc-sales
sudo chown $USER:$USER /var/backups/cmc-sales
```
### 2. Install Caddy
```bash
# Run the installation script
sudo ./scripts/install-caddy.sh
# Or manually install
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
```
### 3. DNS Configuration
Ensure 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
nano .env.staging
nano .env.production
# Create credential directories
mkdir -p credentials/staging credentials/production
```
### 3. Setup Basic Authentication
```bash
# Generate password hashes for Caddy
./scripts/setup-caddy-auth.sh
# Or manually
caddy hash-password
# Copy the hash and update Caddyfile
```
### 4. Configure Caddy
```bash
# Copy Caddyfile
sudo cp Caddyfile /etc/caddy/Caddyfile
# Edit to update passwords and email
sudo nano /etc/caddy/Caddyfile
# Validate configuration
caddy validate --config /etc/caddy/Caddyfile
# Start Caddy
sudo systemctl start caddy
sudo systemctl status caddy
```
### 5. Gmail OAuth Setup
Same as before - set up OAuth credentials for each environment:
- Staging: `credentials/staging/credentials.json`
- Production: `credentials/production/credentials.json`
### 6. Database Initialization
```bash
# Start database containers
docker compose -f docker-compose.caddy-staging.yml up -d db-staging
docker compose -f docker-compose.caddy-production.yml up -d db-production
# Wait for databases
sleep 30
# Restore production database (if you have a backup)
./scripts/restore-db.sh production /path/to/backup.sql.gz
```
## Deployment Commands
### Starting Services
```bash
# Start staging environment
docker compose -f docker-compose.caddy-staging.yml up -d
# Start production environment
docker compose -f docker-compose.caddy-production.yml up -d
# Reload Caddy configuration
sudo systemctl reload caddy
```
### Updating Applications
```bash
# Pull latest code
git pull origin main
# Update staging
docker compose -f docker-compose.caddy-staging.yml down
docker compose -f docker-compose.caddy-staging.yml build --no-cache
docker compose -f docker-compose.caddy-staging.yml up -d
# Test staging, then update production
docker compose -f docker-compose.caddy-production.yml down
docker compose -f docker-compose.caddy-production.yml build --no-cache
docker compose -f docker-compose.caddy-production.yml up -d
```
## Caddy Management
### Configuration
```bash
# Edit Caddyfile
sudo nano /etc/caddy/Caddyfile
# Validate configuration
caddy validate --config /etc/caddy/Caddyfile
# Reload configuration (zero downtime)
sudo systemctl reload caddy
```
### Monitoring
```bash
# Check Caddy status
sudo systemctl status caddy
# View Caddy logs
sudo journalctl -u caddy -f
# View access logs
sudo tail -f /var/log/caddy/cmc-production.log
sudo tail -f /var/log/caddy/cmc-staging.log
```
### SSL Certificates
Caddy handles SSL automatically! To check certificates:
```bash
# List certificates
sudo ls -la /var/lib/caddy/.local/share/caddy/certificates/
# Force certificate renewal (rarely needed)
sudo systemctl stop caddy
sudo rm -rf /var/lib/caddy/.local/share/caddy/certificates/*
sudo systemctl start caddy
```
## Container Port Mapping
| Service | Container Port | Host Port | Access |
|---------|---------------|-----------|---------|
| cmc-php-staging | 80 | 8091 | localhost only |
| cmc-go-staging | 8080 | 8092 | localhost only |
| cmc-db-staging | 3306 | 3307 | localhost only |
| cmc-php-production | 80 | 8093 | localhost only |
| cmc-go-production | 8080 | 8094 | localhost only |
| cmc-db-production | 3306 | - | internal only |
## Monitoring and Maintenance
### Health Checks
```bash
# Check all containers
docker ps
# Check application health
curl -I https://cmc.springupsoftware.com
curl -I https://staging.cmc.springupsoftware.com
# Internal health checks (from server)
curl http://localhost:8094/api/v1/health # Production Go
curl http://localhost:8092/api/v1/health # Staging Go
```
### Database Backups
Same backup scripts work:
```bash
# Manual backup
./scripts/backup-db.sh production
./scripts/backup-db.sh staging
# Automated backups
sudo crontab -e
# Add:
# 0 2 * * * /home/cmc/cmc-sales/scripts/backup-db.sh production
# 0 3 * * * /home/cmc/cmc-sales/scripts/backup-db.sh staging
```
## Security Benefits with Caddy
1. **Automatic HTTPS**: No manual certificate management
2. **Modern TLS**: Always up-to-date TLS configuration
3. **OCSP Stapling**: Enabled by default
4. **Security Headers**: Easy to configure
5. **Rate Limiting**: Built-in support
## Troubleshooting
### Caddy Issues
```bash
# Check Caddy configuration
caddy validate --config /etc/caddy/Caddyfile
# Check Caddy service
sudo systemctl status caddy
sudo journalctl -u caddy -n 100
# Test reverse proxy
curl -v http://localhost:8094/api/v1/health
```
### Container Issues
```bash
# Check container logs
docker compose -f docker-compose.caddy-production.yml logs -f
# Restart specific service
docker compose -f docker-compose.caddy-production.yml restart cmc-go-production
```
### SSL Issues
```bash
# Caddy automatically handles SSL, but if issues arise:
# 1. Check DNS is resolving correctly
dig cmc.springupsoftware.com
# 2. Check Caddy can reach Let's Encrypt
sudo journalctl -u caddy | grep -i acme
# 3. Ensure ports 80 and 443 are open
sudo ufw status
```
## Advantages of Caddy Setup
1. **Simpler Configuration**: Caddyfile is more readable than nginx
2. **Automatic HTTPS**: No certbot or lego needed
3. **Zero-Downtime Reloads**: Config changes without dropping connections
4. **Better Performance**: More efficient than nginx for this use case
5. **Native Rate Limiting**: Built-in without additional modules
6. **Automatic Certificate Renewal**: No cron jobs needed
## Migration from Nginx
If migrating from the nginx setup:
1. Stop nginx containers: `docker compose -f docker-compose.proxy.yml down`
2. Install and configure Caddy
3. Start new containers with caddy compose files
4. Update DNS if needed
5. Monitor logs during transition
## File Structure
```
/home/cmc/cmc-sales/
├── docker-compose.caddy-staging.yml
├── docker-compose.caddy-production.yml
├── Caddyfile
├── credentials/
│ ├── staging/
│ └── production/
├── scripts/
│ ├── backup-db.sh
│ ├── restore-db.sh
│ ├── install-caddy.sh
│ └── setup-caddy-auth.sh
└── .env files
/etc/caddy/
└── Caddyfile (deployed config)
/var/log/caddy/
├── cmc-production.log
└── cmc-staging.log
```