- Convert multi-file overlay approach to single docker-compose.yml - Use environment variables for dev/production differences - Remove complex network configuration conflicts - Align with framework principles: simplicity over complexity - Production config via .env.production file Benefits: - No more network subnet conflicts - Single source of truth - Framework-compliant architecture - Easier maintenance and debugging Related: #19 Docker network conflict resolution
211 lines
5.4 KiB
YAML
211 lines
5.4 KiB
YAML
# Production overlay for Custom PHP Framework
|
|
# Extends base docker-compose.yml with production optimizations
|
|
version: '3.8'
|
|
|
|
services:
|
|
web:
|
|
environment:
|
|
- APP_ENV=production
|
|
- PHP_IDE_CONFIG= # Remove IDE config in production
|
|
ports:
|
|
# Remove development ports, only expose HTTPS
|
|
- "${APP_SSL_PORT:-443}:443/tcp"
|
|
- "443:443/udp"
|
|
volumes:
|
|
# Read-only application code in production
|
|
- ./:/var/www/html:ro
|
|
- ./ssl:/var/www/ssl:ro
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "-k", "https://localhost/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 30s
|
|
restart: always
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
labels: "service=nginx,environment=production"
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 256M
|
|
cpus: '0.5'
|
|
reservations:
|
|
memory: 128M
|
|
cpus: '0.25'
|
|
|
|
php:
|
|
environment:
|
|
APP_ENV: production
|
|
APP_DEBUG: false
|
|
PHP_IDE_CONFIG: "" # Remove IDE config
|
|
XDEBUG_MODE: off # Disable Xdebug in production
|
|
build:
|
|
args:
|
|
- ENV=production
|
|
- COMPOSER_INSTALL_FLAGS=--no-dev --optimize-autoloader --classmap-authoritative
|
|
user: "www-data:www-data" # Use www-data in production
|
|
volumes:
|
|
# Read-only application code
|
|
- ./:/var/www/html:ro
|
|
# Writable storage volumes
|
|
- storage-data:/var/www/html/storage:rw
|
|
- var-data:/var/www/html/var:rw
|
|
# Composer cache (but less aggressive caching in prod)
|
|
- composer-cache:/var/www/.composer/cache
|
|
healthcheck:
|
|
test: ["CMD", "php", "/var/www/html/public/health.php"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 60s
|
|
restart: always
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
labels: "service=php,environment=production"
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 512M
|
|
cpus: '1.0'
|
|
reservations:
|
|
memory: 256M
|
|
cpus: '0.5'
|
|
|
|
db:
|
|
environment:
|
|
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
|
|
- MYSQL_DATABASE=${DB_DATABASE}
|
|
- MYSQL_USER=${DB_USERNAME}
|
|
- MYSQL_PASSWORD=${DB_PASSWORD}
|
|
ports: [] # No external ports in production
|
|
volumes:
|
|
- db_data:/var/lib/mysql
|
|
# Production MySQL configuration
|
|
- ./docker/mysql/conf.d/security.cnf:/etc/mysql/conf.d/security.cnf:ro
|
|
healthcheck:
|
|
test: ["CMD", "mariadb-admin", "ping", "-h", "127.0.0.1", "-u", "root", "-p${DB_ROOT_PASSWORD}"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 5
|
|
start_period: 60s
|
|
restart: always
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
labels: "service=mariadb,environment=production"
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 1G
|
|
cpus: '1.0'
|
|
reservations:
|
|
memory: 512M
|
|
cpus: '0.5'
|
|
|
|
redis:
|
|
volumes:
|
|
# Use secure Redis configuration in production
|
|
- ./docker/redis/redis-secure.conf:/usr/local/etc/redis/redis.conf:ro
|
|
- redis_data:/data
|
|
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 30s
|
|
restart: always
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
labels: "service=redis,environment=production"
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 256M
|
|
cpus: '0.5'
|
|
reservations:
|
|
memory: 128M
|
|
cpus: '0.25'
|
|
|
|
queue-worker:
|
|
environment:
|
|
- APP_ENV=production
|
|
- APP_DEBUG=false
|
|
- WORKER_DEBUG=false
|
|
- WORKER_SLEEP_TIME=${WORKER_SLEEP_TIME:-100000}
|
|
- WORKER_MAX_JOBS=${WORKER_MAX_JOBS:-1000}
|
|
- WORKER_MEMORY_LIMIT=${WORKER_MEMORY_LIMIT:-384M}
|
|
build:
|
|
args:
|
|
- ENV=production
|
|
- COMPOSER_INSTALL_FLAGS=--no-dev --optimize-autoloader
|
|
user: "www-data:www-data"
|
|
volumes:
|
|
# Read-only application code
|
|
- ./:/var/www/html:ro
|
|
# Writable logs and storage
|
|
- ./storage/logs:/var/www/html/storage/logs:rw
|
|
- ./src/Framework/CommandBus/storage:/var/www/html/src/Framework/CommandBus/storage:rw
|
|
restart: always
|
|
stop_grace_period: 60s # Longer grace period for production
|
|
logging:
|
|
driver: "json-file"
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
labels: "service=queue-worker,environment=production"
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 512M
|
|
cpus: '0.5'
|
|
reservations:
|
|
memory: 256M
|
|
cpus: '0.25'
|
|
|
|
# Security-focused network configuration
|
|
networks:
|
|
frontend:
|
|
driver: bridge
|
|
ipam:
|
|
driver: default
|
|
config:
|
|
- subnet: 172.24.0.0/24
|
|
backend:
|
|
driver: bridge
|
|
internal: true # Backend network is internal-only
|
|
ipam:
|
|
driver: default
|
|
config:
|
|
- subnet: 172.25.0.0/24
|
|
cache:
|
|
driver: bridge
|
|
internal: true # Cache network is internal-only
|
|
ipam:
|
|
driver: default
|
|
config:
|
|
- subnet: 172.26.0.0/24
|
|
|
|
volumes:
|
|
redis_data:
|
|
driver: local
|
|
composer-cache:
|
|
driver: local
|
|
storage-data:
|
|
driver: local
|
|
var-data:
|
|
driver: local
|
|
db_data:
|
|
driver: local |