Docker Queue & Horizon Setup
This directory bundles ready-to-use entrypoint scripts and deployment notes for running Fotospiel’s queue workers inside Docker containers. The examples assume you already run the main application in Docker (e.g. via docker-compose.yml) and share the same application image for workers.
1. Prepare the application image
Make sure the worker scripts are copied into the image and marked as executable:
# Dockerfile
COPY docs/queue-supervisor /var/www/html/docs/queue-supervisor
RUN chmod +x /var/www/html/docs/queue-supervisor/*.sh
If you keep the project root mounted as a volume during development the chmod step can be skipped because the files will inherit host permissions.
2. Queue worker containers
Add one or more worker services to docker-compose.yml. The production compose file in the repo already defines queue and media-storage-worker services that call these scripts; the snippet below shows the essential pattern if you need to tweak scaling.
services:
queue-worker:
image: fotospiel-app # reuse the main app image
restart: unless-stopped
depends_on:
- redis # or your queue backend
environment:
APP_ENV: ${APP_ENV:-production}
QUEUE_CONNECTION: redis
QUEUE_TRIES: 3 # optional overrides
QUEUE_SLEEP: 3
command: >
/var/www/html/docs/queue-supervisor/queue-worker.sh default
media-storage-worker:
image: fotospiel-app
restart: unless-stopped
depends_on:
- redis
environment:
APP_ENV: ${APP_ENV:-production}
QUEUE_CONNECTION: redis
QUEUE_TRIES: 5
QUEUE_SLEEP: 5
command: >
/var/www/html/docs/queue-supervisor/queue-worker.sh media-storage
media-security-worker:
image: fotospiel-app
restart: unless-stopped
depends_on:
- redis
environment:
APP_ENV: ${APP_ENV:-production}
QUEUE_CONNECTION: redis
QUEUE_TRIES: 3
QUEUE_SLEEP: 5
command: >
/var/www/html/docs/queue-supervisor/queue-worker.sh media-security
Scale workers by increasing deploy.replicas (Swarm) or adding scale counts (Compose v2).
3. Optional: Horizon container
If you prefer Horizon’s dashboard and auto-balancing, add another service:
services:
horizon:
image: fotospiel-app
restart: unless-stopped
depends_on:
- redis
environment:
APP_ENV: ${APP_ENV:-production}
QUEUE_CONNECTION: redis
command: >
/var/www/html/docs/queue-supervisor/horizon.sh
Expose Horizon via your web proxy and protect it with authentication (the app already guards /horizon behind the super admin panel login if configured).
4. Environment variables
QUEUE_CONNECTION— should match the driver configured in.env(redisrecommended).QUEUE_TRIES,QUEUE_SLEEP,QUEUE_TIMEOUT,QUEUE_MAX_TIME— optional tuning knobs consumed byqueue-worker.sh.STORAGE_ALERT_EMAIL— enables upload failure notifications introduced in the new storage pipeline.SECURITY_SCAN_QUEUE— overrides the queue name for the photo antivirus/EXIF worker (media-securityby default).- Redis / database credentials must be available in the worker containers exactly like the web container.
5. Bootstrapping reminder
Before starting workers on a new environment:
php artisan migrate
php artisan db:seed --class=MediaStorageTargetSeeder
Existing assets should be backfilled into event_media_assets with a one-off artisan command before enabling automatic archival jobs.
6. Monitoring & logs
- Containers log to STDOUT; aggregate via
docker logsor a centralized stack. - Horizon users can inspect
/horizonfor queue lengths and failed jobs. - With plain workers run
php artisan queue:failed(inside the container) to inspect failures andphp artisan queue:retry allafter resolving issues.
7. Rolling updates
When deploying new code:
- Build and push updated app image.
- Run migrations & seeders.
- Recreate worker/horizon containers:
docker compose up -d --force-recreate queue-worker media-storage-worker horizon. - Tail logs to confirm workers boot cleanly and start consuming jobs.
8. Running inside Coolify
If you host Fotospiel on Coolify:
- Create separate Coolify “services” for each worker type using the same image and command snippets above (
queue-worker.sh default,media-storage, etc.). - Attach the same environment variables and storage volumes defined for the main app.
- Use Coolify’s “One-off command” feature to run migrations or
queue:retry. - Expose the Horizon service through Coolify’s HTTP proxy (or keep it internal and access via SSH tunnel).
- Enable health checks so Coolify restarts workers automatically if they exit unexpectedly.
These services can be observed and restarted from Coolify’s dashboard; the upcoming SuperAdmin integration will surface the same metrics/actions through a dedicated Filament widget.