344 lines
8 KiB
Markdown
344 lines
8 KiB
Markdown
|
|
# 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
|
||
|
|
```
|