version: '3.8' services: # PHP-FPM Application Runtime app: image: git.michaelschiemer.de:5000/framework:latest container_name: app restart: unless-stopped networks: - app-internal environment: - TZ=Europe/Berlin - APP_ENV=${APP_ENV:-production} - APP_DEBUG=${APP_DEBUG:-false} - APP_URL=${APP_URL:-https://michaelschiemer.de} # Database - DB_HOST=${DB_HOST:-mysql} - DB_PORT=${DB_PORT:-3306} - DB_NAME=${DB_NAME} - DB_USER=${DB_USER} - DB_PASS=${DB_PASS} # Redis - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD} # Cache - CACHE_DRIVER=redis - CACHE_PREFIX=${CACHE_PREFIX:-app} # Session - SESSION_DRIVER=redis - SESSION_LIFETIME=${SESSION_LIFETIME:-120} # Queue - QUEUE_DRIVER=redis - QUEUE_CONNECTION=default volumes: - app-storage:/var/www/html/storage - app-logs:/var/www/html/storage/logs - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro healthcheck: test: ["CMD-SHELL", "php-fpm-healthcheck"] interval: 30s timeout: 10s retries: 3 start_period: 40s depends_on: redis: condition: service_healthy # Nginx Web Server nginx: image: nginx:1.25-alpine container_name: nginx restart: unless-stopped networks: - traefik-public - app-internal environment: - TZ=Europe/Berlin volumes: - ./nginx/conf.d:/etc/nginx/conf.d:ro - app-storage:/var/www/html/storage:ro - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro labels: - "traefik.enable=true" # HTTP Router - "traefik.http.routers.app.rule=Host(`${APP_DOMAIN:-michaelschiemer.de}`)" - "traefik.http.routers.app.entrypoints=websecure" - "traefik.http.routers.app.tls=true" - "traefik.http.routers.app.tls.certresolver=letsencrypt" # Service - "traefik.http.services.app.loadbalancer.server.port=80" # Middleware - "traefik.http.routers.app.middlewares=default-chain@file" # Network - "traefik.docker.network=traefik-public" healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s depends_on: app: condition: service_healthy # Redis Cache/Session/Queue Backend redis: image: redis:7-alpine container_name: redis restart: unless-stopped networks: - app-internal environment: - TZ=Europe/Berlin command: > redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 512mb --maxmemory-policy allkeys-lru --save 900 1 --save 300 10 --save 60 10000 --appendonly yes --appendfsync everysec volumes: - redis-data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 30s timeout: 10s retries: 3 start_period: 10s # Queue Worker (Background Jobs) queue-worker: image: git.michaelschiemer.de:5000/framework:latest container_name: queue-worker restart: unless-stopped networks: - app-internal environment: - TZ=Europe/Berlin - APP_ENV=${APP_ENV:-production} - APP_DEBUG=${APP_DEBUG:-false} # Database - DB_HOST=${DB_HOST:-mysql} - DB_PORT=${DB_PORT:-3306} - DB_NAME=${DB_NAME} - DB_USER=${DB_USER} - DB_PASS=${DB_PASS} # Redis - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD} # Queue - QUEUE_DRIVER=redis - QUEUE_CONNECTION=default - QUEUE_WORKER_SLEEP=${QUEUE_WORKER_SLEEP:-3} - QUEUE_WORKER_TRIES=${QUEUE_WORKER_TRIES:-3} - QUEUE_WORKER_TIMEOUT=${QUEUE_WORKER_TIMEOUT:-60} volumes: - app-storage:/var/www/html/storage - app-logs:/var/www/html/storage/logs - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro command: php console.php queue:work --queue=default --timeout=${QUEUE_WORKER_TIMEOUT:-60} healthcheck: test: ["CMD-SHELL", "pgrep -f 'queue:work' || exit 1"] interval: 60s timeout: 10s retries: 3 start_period: 30s depends_on: app: condition: service_healthy redis: condition: service_healthy # Scheduler (Cron Jobs) scheduler: image: git.michaelschiemer.de:5000/framework:latest container_name: scheduler restart: unless-stopped networks: - app-internal environment: - TZ=Europe/Berlin - APP_ENV=${APP_ENV:-production} - APP_DEBUG=${APP_DEBUG:-false} # Database - DB_HOST=${DB_HOST:-mysql} - DB_PORT=${DB_PORT:-3306} - DB_NAME=${DB_NAME} - DB_USER=${DB_USER} - DB_PASS=${DB_PASS} # Redis - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD} volumes: - app-storage:/var/www/html/storage - app-logs:/var/www/html/storage/logs - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro command: php console.php scheduler:run healthcheck: test: ["CMD-SHELL", "pgrep -f 'scheduler:run' || exit 1"] interval: 60s timeout: 10s retries: 3 start_period: 30s depends_on: app: condition: service_healthy redis: condition: service_healthy volumes: app-storage: name: app-storage app-logs: name: app-logs redis-data: name: redis-data networks: traefik-public: external: true app-internal: name: app-internal driver: bridge