# Production-specific Docker Compose overrides # Usage: docker-compose -f docker-compose.yml -f docker-compose.production.yml --env-file .env.production up -d # # This file overrides base configuration with production-specific settings: # - Stricter resource limits # - Production restart policies (always) # - JSON logging with proper rotation # - No host mounts (security) # - Internal networks (security) # - Production PostgreSQL configuration # - Certbot for SSL certificates version: '3.8' services: web: # Production restart policy restart: always # Override volumes - use Let's Encrypt certificates volumes: - certbot-conf:/etc/letsencrypt:ro - certbot-www:/var/www/certbot:ro # Remove development host mounts for security # Application code deployed via Docker image build environment: - APP_ENV=production - APP_DEBUG=false # Stricter health checks for production healthcheck: test: ["CMD", "curl", "-f", "https://localhost/health"] interval: 15s timeout: 5s retries: 5 start_period: 30s # JSON logging with rotation logging: driver: json-file options: max-size: "10m" max-file: "5" compress: "true" labels: "service,environment" # Production resource limits (Nginx is lightweight) deploy: resources: limits: memory: 512M cpus: '1.0' reservations: memory: 256M cpus: '0.5' depends_on: php: condition: service_healthy certbot: condition: service_started php: # Production restart policy restart: always # Override build args for production build: args: - ENV=production - COMPOSER_INSTALL_FLAGS=--no-dev --optimize-autoloader --classmap-authoritative environment: - APP_ENV=production - APP_DEBUG=false - PHP_MEMORY_LIMIT=512M - PHP_MAX_EXECUTION_TIME=30 # Disable Xdebug in production - XDEBUG_MODE=off # Stricter health checks healthcheck: test: ["CMD", "php-fpm-healthcheck"] interval: 15s timeout: 5s retries: 5 start_period: 30s # JSON logging logging: driver: json-file options: max-size: "10m" max-file: "10" compress: "true" labels: "service,environment" # Production resource limits deploy: resources: limits: memory: 1G cpus: '2.0' reservations: memory: 512M cpus: '1.0' # Remove development volumes volumes: # Keep only necessary volumes - storage-logs:/var/www/html/storage/logs:rw - storage-cache:/var/www/html/storage/cache:rw - storage-queue:/var/www/html/storage/queue:rw - storage-discovery:/var/www/html/storage/discovery:rw - storage-uploads:/var/www/html/storage/uploads:rw db: # Production restart policy restart: always # Use production PostgreSQL configuration volumes: - db_data:/var/lib/postgresql/data - ./docker/postgres/postgresql.production.conf:/etc/postgresql/postgresql.conf:ro - ./docker/postgres/init:/docker-entrypoint-initdb.d:ro # Production resource limits deploy: resources: limits: memory: 2G cpus: '2.0' reservations: memory: 1G cpus: '1.0' # Stricter health checks healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-postgres} -d ${DB_DATABASE:-michaelschiemer}"] interval: 10s timeout: 3s retries: 5 start_period: 30s # JSON logging logging: driver: json-file options: max-size: "20m" max-file: "10" compress: "true" labels: "service,environment" redis: # Production restart policy restart: always # Production resource limits deploy: resources: limits: memory: 512M cpus: '1.0' reservations: memory: 256M cpus: '0.5' # Stricter health checks healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 3s retries: 5 start_period: 10s # JSON logging logging: driver: json-file options: max-size: "10m" max-file: "5" compress: "true" labels: "service,environment" queue-worker: # Production restart policy restart: always environment: - APP_ENV=production - WORKER_DEBUG=false - WORKER_SLEEP_TIME=100000 - WORKER_MAX_JOBS=10000 # Production resource limits deploy: resources: limits: memory: 2G cpus: '2.0' reservations: memory: 1G cpus: '1.0' # Scale queue workers in production replicas: 2 # JSON logging logging: driver: json-file options: max-size: "20m" max-file: "10" compress: "true" labels: "service,environment" # Graceful shutdown for long-running jobs stop_grace_period: 60s # Certbot Sidecar Container for Let's Encrypt certbot: image: certbot/certbot:latest container_name: certbot restart: always volumes: # Share certificates with Nginx - certbot-conf:/etc/letsencrypt - certbot-www:/var/www/certbot # Logs for debugging - certbot-logs:/var/log/letsencrypt # Auto-renewal every 12 hours entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot --quiet; sleep 12h & wait $${!}; done;'" networks: - frontend # JSON logging logging: driver: json-file options: max-size: "5m" max-file: "3" compress: "true" labels: "service,environment" networks: # Production networks with security isolation frontend: driver: bridge backend: driver: bridge internal: true # Backend network is internal (no internet access) cache: driver: bridge internal: true # Cache network is internal volumes: # Let's Encrypt SSL Certificates certbot-conf: driver: local certbot-www: driver: local certbot-logs: driver: local # Application storage volumes storage-logs: driver: local storage-cache: driver: local storage-queue: driver: local storage-discovery: driver: local storage-uploads: driver: local # Database volume with backup driver (optional) db_data: driver: local # Optional: Use external volume for easier backups # driver_opts: # type: none # o: bind # device: /mnt/db-backups/michaelschiemer-prod