Add docker-compose.caddy and Makefile

This commit is contained in:
Karl Cordes 2025-08-07 21:53:30 +10:00
parent 30f84fefe7
commit dc2b67d300
3 changed files with 336 additions and 0 deletions

190
Makefile Normal file
View file

@ -0,0 +1,190 @@
# CMC Sales Deployment Makefile for Caddy setup
.PHONY: help staging production backup-staging backup-production restart-staging restart-production status logs clean caddy-reload caddy-logs
# Default target
help:
@echo "CMC Sales Deployment Commands (Caddy version)"
@echo ""
@echo "Environments:"
@echo " staging Start staging environment"
@echo " staging-down Stop staging environment"
@echo " staging-logs Show staging logs"
@echo " restart-staging Rebuild and restart staging"
@echo ""
@echo " production Start production environment"
@echo " production-down Stop production environment"
@echo " production-logs Show production logs"
@echo " restart-production Rebuild and restart production"
@echo ""
@echo "Database:"
@echo " backup-staging Backup staging database"
@echo " backup-production Backup production database"
@echo ""
@echo "Caddy:"
@echo " caddy-status Show Caddy service status"
@echo " caddy-reload Reload Caddy configuration"
@echo " caddy-logs Show Caddy logs"
@echo " caddy-validate Validate Caddyfile"
@echo ""
@echo "Utility:"
@echo " status Show all container status"
@echo " clean Stop and remove all containers"
@echo " setup-auth Setup basic authentication"
# Staging environment
staging:
@echo "Starting staging environment..."
docker compose -f docker-compose.caddy-staging.yml up -d
@echo "Staging environment started"
@echo "Access at: https://staging.cmc.springupsoftware.com"
staging-down:
docker compose -f docker-compose.caddy-staging.yml down
staging-logs:
docker compose -f docker-compose.caddy-staging.yml logs -f
restart-staging:
@echo "Restarting staging environment..."
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
@echo "Staging environment restarted"
# Production environment
production:
@echo "Starting production environment..."
docker compose -f docker-compose.caddy-production.yml up -d
@echo "Production environment started"
@echo "Access at: https://cmc.springupsoftware.com"
production-down:
@echo "WARNING: This will stop the production environment!"
@read -p "Are you sure? (yes/no): " confirm && [ "$$confirm" = "yes" ]
docker compose -f docker-compose.caddy-production.yml down
production-logs:
docker compose -f docker-compose.caddy-production.yml logs -f
restart-production:
@echo "WARNING: This will restart the production environment!"
@read -p "Are you sure? (yes/no): " confirm && [ "$$confirm" = "yes" ]
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
@echo "Production environment restarted"
# Database backups
backup-staging:
@echo "Creating staging database backup..."
./scripts/backup-db.sh staging
backup-production:
@echo "Creating production database backup..."
./scripts/backup-db.sh production
# Caddy management
caddy-status:
@echo "=== Caddy Status ==="
sudo systemctl status caddy --no-pager
caddy-reload:
@echo "Reloading Caddy configuration..."
sudo systemctl reload caddy
@echo "Caddy reloaded successfully"
caddy-logs:
@echo "=== Caddy Logs ==="
sudo journalctl -u caddy -f
caddy-validate:
@echo "Validating Caddyfile..."
caddy validate --config Caddyfile
@echo "Caddyfile is valid"
# Setup authentication
setup-auth:
@echo "Setting up basic authentication..."
./scripts/setup-caddy-auth.sh
# System status
status:
@echo "=== Container Status ==="
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
@echo ""
@echo "=== Caddy Status ==="
sudo systemctl is-active caddy || true
@echo ""
@echo "=== Port Usage ==="
sudo netstat -tlnp | grep -E ":(80|443|8091|8092|8093|8094|3306|3307) " || true
# Logs
logs:
@echo "Which logs? [staging/production/caddy]"
@read env; \
case $$env in \
staging) docker compose -f docker-compose.caddy-staging.yml logs -f ;; \
production) docker compose -f docker-compose.caddy-production.yml logs -f ;; \
caddy) sudo journalctl -u caddy -f ;; \
*) echo "Invalid option" ;; \
esac
# Cleanup
clean:
@echo "WARNING: This will stop and remove ALL CMC containers!"
@read -p "Are you sure? (yes/no): " confirm && [ "$$confirm" = "yes" ]
docker compose -f docker-compose.caddy-staging.yml down --volumes --remove-orphans
docker compose -f docker-compose.caddy-production.yml down --volumes --remove-orphans
docker system prune -f
@echo "Cleanup completed"
# Health checks
health:
@echo "=== Health Checks ==="
@echo "Staging:"
@curl -s -o /dev/null -w " HTTPS %{http_code}: https://staging.cmc.springupsoftware.com/health\n" https://staging.cmc.springupsoftware.com/health -u admin:password || echo " Staging not accessible (update with correct auth)"
@curl -s -o /dev/null -w " Internal %{http_code}: http://localhost:8092/api/v1/health\n" http://localhost:8092/api/v1/health || echo " Staging Go not accessible"
@echo "Production:"
@curl -s -o /dev/null -w " HTTPS %{http_code}: https://cmc.springupsoftware.com/health\n" https://cmc.springupsoftware.com/health -u admin:password || echo " Production not accessible (update with correct auth)"
@curl -s -o /dev/null -w " Internal %{http_code}: http://localhost:8094/api/v1/health\n" http://localhost:8094/api/v1/health || echo " Production Go not accessible"
# Deploy to staging
deploy-staging:
@echo "Deploying to staging..."
git pull origin main
$(MAKE) restart-staging
@echo "Staging deployment complete"
# Deploy to production
deploy-production:
@echo "WARNING: This will deploy to PRODUCTION!"
@echo "Make sure you have tested thoroughly in staging first."
@read -p "Are you sure you want to deploy to production? (yes/no): " confirm && [ "$$confirm" = "yes" ]
git pull origin main
$(MAKE) backup-production
$(MAKE) restart-production
@echo "Production deployment complete"
# First-time setup
initial-setup:
@echo "Running initial setup..."
@echo "1. Installing Caddy..."
sudo ./scripts/install-caddy.sh
@echo ""
@echo "2. Setting up authentication..."
./scripts/setup-caddy-auth.sh
@echo ""
@echo "3. Copying Caddyfile..."
sudo cp Caddyfile /etc/caddy/Caddyfile
@echo ""
@echo "4. Starting Caddy..."
sudo systemctl start caddy
@echo ""
@echo "5. Starting containers..."
$(MAKE) staging
$(MAKE) production
@echo ""
@echo "Initial setup complete!"
@echo "Access staging at: https://staging.cmc.springupsoftware.com"
@echo "Access production at: https://cmc.springupsoftware.com"

View file

@ -0,0 +1,85 @@
version: '3.8'
services:
cmc-php-production:
build:
context: .
dockerfile: Dockerfile
platform: linux/amd64
container_name: cmc-php-production
depends_on:
- db-production
ports:
- "127.0.0.1:8093:80" # Only accessible from localhost
volumes:
- production_pdf_data:/var/www/cmc-sales/app/webroot/pdf
- production_attachments_data:/var/www/cmc-sales/app/webroot/attachments_files
restart: unless-stopped
environment:
- APP_ENV=production
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
db-production:
image: mariadb:latest
container_name: cmc-db-production
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD_PRODUCTION}
MYSQL_DATABASE: cmc
MYSQL_USER: cmc
MYSQL_PASSWORD: ${DB_PASSWORD_PRODUCTION}
volumes:
- production_db_data:/var/lib/mysql
- ./backups:/backups:ro
restart: unless-stopped
# No external port exposure for security
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
reservations:
cpus: '0.5'
memory: 1G
cmc-go-production:
build:
context: .
dockerfile: Dockerfile.go.production
container_name: cmc-go-production
environment:
DB_HOST: db-production
DB_PORT: 3306
DB_USER: cmc
DB_PASSWORD: ${DB_PASSWORD_PRODUCTION}
DB_NAME: cmc
PORT: 8080
APP_ENV: production
depends_on:
db-production:
condition: service_started
ports:
- "127.0.0.1:8094:8080" # Only accessible from localhost
volumes:
- production_pdf_data:/root/webroot/pdf
- ./credentials/production:/root/credentials:ro
restart: unless-stopped
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
volumes:
production_db_data:
production_pdf_data:
production_attachments_data:

View file

@ -0,0 +1,61 @@
version: '3.8'
services:
cmc-php-staging:
build:
context: .
dockerfile: Dockerfile
platform: linux/amd64
container_name: cmc-php-staging
depends_on:
- db-staging
ports:
- "127.0.0.1:8091:80" # Only accessible from localhost
volumes:
- staging_pdf_data:/var/www/cmc-sales/app/webroot/pdf
- staging_attachments_data:/var/www/cmc-sales/app/webroot/attachments_files
restart: unless-stopped
environment:
- APP_ENV=staging
db-staging:
image: mariadb:latest
container_name: cmc-db-staging
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD_STAGING}
MYSQL_DATABASE: cmc_staging
MYSQL_USER: cmc_staging
MYSQL_PASSWORD: ${DB_PASSWORD_STAGING}
volumes:
- staging_db_data:/var/lib/mysql
restart: unless-stopped
ports:
- "127.0.0.1:3307:3306" # Only accessible from localhost
cmc-go-staging:
build:
context: .
dockerfile: Dockerfile.go.staging
container_name: cmc-go-staging
environment:
DB_HOST: db-staging
DB_PORT: 3306
DB_USER: cmc_staging
DB_PASSWORD: ${DB_PASSWORD_STAGING}
DB_NAME: cmc_staging
PORT: 8080
APP_ENV: staging
depends_on:
db-staging:
condition: service_started
ports:
- "127.0.0.1:8092:8080" # Only accessible from localhost
volumes:
- staging_pdf_data:/root/webroot/pdf
- ./credentials/staging:/root/credentials:ro
restart: unless-stopped
volumes:
staging_db_data:
staging_pdf_data:
staging_attachments_data: