@@ -121,7 +121,7 @@ services:
121121
122122 # Cache
123123 CACHE_STORE : " ${CACHE_STORE:-file}"
124- CACHE_PREFIX : " ${CACHE_PREFIX:-lychee_keygen_cache }"
124+ CACHE_PREFIX : " ${CACHE_PREFIX:-lychee_cache }"
125125 REDIS_HOST : " lychee_cache"
126126 REDIS_PASSWORD : " null"
127127 REDIS_PORT : " 6379"
@@ -142,8 +142,6 @@ services:
142142 LOG_LEVEL : " ${LOG_LEVEL:-debug}"
143143 LOG_STDOUT : " ${LOG_STDOUT:-true}"
144144
145- # QUEUE_CONNECTION:sync
146-
147145 # SECURITY_HEADER_HSTS_ENABLE:false
148146 # SECURITY_HEADER_CSP_CONNECT_SRC:
149147 # SECURITY_HEADER_SCRIPT_SRC_ALLOW:
@@ -288,6 +286,131 @@ services:
288286 networks :
289287 - lychee
290288
289+ # Queue Worker Service (disabled by default)
290+ # Uncomment to enable horizontal scaling of background job processing
291+ lychee_worker :
292+ image : lychee-frankenphp:latest
293+ # build:
294+ # context: ./app
295+ # dockerfile: Dockerfile
296+ # args:
297+ # NODE_ENV: "${NODE_ENV:-production}"
298+ container_name : lychee-worker
299+ restart : unless-stopped # Auto-restart at container level (outer layer)
300+
301+ # Security hardening (match lychee_api)
302+ security_opt :
303+ - no-new-privileges:true
304+ - seccomp:unconfined
305+ cap_drop :
306+ - ALL
307+ cap_add :
308+ - CHOWN
309+ - SETGID
310+ - SETUID
311+ - DAC_OVERRIDE
312+ read_only : false # Laravel needs write access to storage/cache
313+ tmpfs :
314+ - /tmp:noexec,nosuid,nodev,size=100m
315+
316+ # Resource limits (adjust based on workload)
317+ # Workers typically need less CPU but more memory for image processing
318+ deploy :
319+ resources :
320+ limits :
321+ cpus : ' 2'
322+ memory : 2G
323+ reservations :
324+ cpus : ' 0.5'
325+ memory : 512M
326+
327+ env_file :
328+ - path : ./.env
329+ required : true
330+ environment :
331+ PUID : " ${PUID:-1000}"
332+ PGID : " ${PGID:-1000}"
333+
334+ # WORKER MODE CONFIGURATION
335+ # Set LYCHEE_MODE=worker to enable queue worker mode
336+ LYCHEE_MODE : worker
337+
338+ # Queue configuration (CRITICAL for worker mode)
339+ # Recommended: redis for production (faster, better concurrency)
340+ # Alternative: database (no Redis dependency)
341+ QUEUE_CONNECTION : " ${QUEUE_CONNECTION:-database}"
342+
343+ # Queue priority (optional)
344+ # Process high-priority jobs first, then default, then low
345+ # Example: QUEUE_NAMES=high,default,low
346+ # QUEUE_NAMES: "${QUEUE_NAMES:-default}"
347+
348+ # Worker restart interval (optional)
349+ # Restart worker after N seconds to mitigate memory leaks
350+ # Default: 3600 seconds (1 hour)
351+ # WORKER_MAX_TIME: "${WORKER_MAX_TIME:-3600}"
352+
353+ # Application (inherit from lychee_api)
354+ APP_NAME : " ${APP_NAME:-Lychee}"
355+ APP_ENV : " ${APP_ENV:-production}"
356+ APP_DEBUG : " ${APP_DEBUG:-false}"
357+ APP_TIMEZONE : " ${TIMEZONE:-UTC}"
358+ APP_URL : " ${APP_URL:-http://localhost:8000}"
359+
360+ # Database (same as lychee_api - shared database required)
361+ DB_CONNECTION : " ${DB_CONNECTION:-mysql}"
362+ DB_HOST : " ${DB_HOST:-lychee_db}"
363+ DB_PORT : " ${DB_PORT:-3306}"
364+ DB_DATABASE : " ${DB_DATABASE:-lychee}"
365+ DB_USERNAME : " ${DB_USERNAME:-lychee}"
366+ # DB_PASSWORD comes from .env file
367+
368+ # Redis (if using redis queue driver)
369+ # Must point to same Redis instance as lychee_api
370+ REDIS_HOST : " lychee_cache"
371+ REDIS_PASSWORD : " null"
372+ REDIS_PORT : " 6379"
373+
374+ # Cache (same as lychee_api)
375+ CACHE_STORE : " ${CACHE_STORE:-file}"
376+ CACHE_PREFIX : " ${CACHE_PREFIX:-lychee_cache}"
377+
378+ # Logging (output to stdout/stderr for container log aggregation)
379+ LOG_CHANNEL : " ${LOG_CHANNEL:-stack}"
380+ LOG_STACK : " ${LOG_STACK:-single}"
381+ LOG_LEVEL : " ${LOG_LEVEL:-debug}"
382+ LOG_STDOUT : " ${LOG_STDOUT:-true}"
383+
384+ # Shared volumes with lychee_api (CRITICAL for photo processing)
385+ # Workers need access to the same uploads and storage as web service
386+ volumes :
387+ - ./lychee/uploads:/app/public/uploads
388+ - ./lychee/storage/app:/app/storage/app
389+ - ./lychee/logs:/app/storage/logs
390+ - ./lychee/tmp:/app/storage/tmp
391+ - .env:/app/.env:ro
392+
393+ depends_on :
394+ lychee_db :
395+ condition : service_healthy
396+
397+ # Worker health check
398+ # Verifies queue:work process is running
399+ healthcheck :
400+ test : ["CMD-SHELL", "pgrep -f 'queue:work' || exit 1"]
401+ interval : 30s
402+ timeout : 10s
403+ retries : 3
404+ start_period : 60s # Give worker time to start up
405+
406+ networks :
407+ - lychee
408+ #
409+ # SCALING WORKERS:
410+ # To run multiple worker containers (horizontal scaling):
411+ # docker compose up -d --scale lychee_worker=3
412+ # This will create 3 worker containers processing jobs in parallel.
413+
291414 lychee_cache :
292415 image : redis:alpine
293416 hostname : lychee_cache
0 commit comments