## 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. Queue entrypoints now live in `/scripts/` inside the container so every service can execute the same shell scripts.

### 1. Prepare the application image

Make sure the worker scripts are copied into the image and marked as executable:

```dockerfile
# Dockerfile (excerpt)
COPY scripts /var/www/html/scripts
RUN chmod +x /var/www/html/scripts/*.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.

```yaml
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/scripts/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/scripts/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/scripts/queue-worker.sh media-security
```

Scale workers by increasing `deploy.replicas` (Swarm) or adding `scale` counts (Compose v2).

> **Heads-up:** Guest push notifications are dispatched on the `notifications` queue. Either add that queue to the default worker (`queue-worker.sh default,notifications`) or create a dedicated worker so push jobs are consumed even when other queues are busy.

### 3. Optional: Horizon container

If you prefer Horizon’s dashboard and auto-balancing, add another service:

```yaml
services:
  horizon:
    image: fotospiel-app
    restart: unless-stopped
    depends_on:
      - redis
    environment:
      APP_ENV: ${APP_ENV:-production}
      QUEUE_CONNECTION: redis
    command: >
      /var/www/html/scripts/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` (`redis` recommended).
- `QUEUE_TRIES`, `QUEUE_SLEEP`, `QUEUE_TIMEOUT`, `QUEUE_MAX_TIME` — optional tuning knobs consumed by `queue-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-security` by 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:

```bash
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 logs` or a centralized stack.
- Horizon users can inspect `/horizon` for queue lengths and failed jobs.
- With plain workers run `php artisan queue:failed` (inside the container) to inspect failures and `php artisan queue:retry all` after resolving issues.

### 7. Rolling updates

When deploying new code:

1. Build and push updated app image.
2. Run migrations & seeders.
3. Recreate worker/horizon containers: `docker compose up -d --force-recreate queue-worker media-storage-worker horizon`.
4. Tail logs to confirm workers boot cleanly and start consuming jobs.

### 8. Running inside Dokploy

If you host Fotospiel on Dokploy:

- Create separate Dokploy applications 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 Dokploy’s one-off command feature to run migrations or `queue:retry`.
- Expose the Horizon service through the Dokploy HTTP proxy (or keep it internal and access via SSH tunnel).
- Enable health checks so Dokploy restarts workers automatically if they exit unexpectedly.

These services can be observed, redeployed, or reloaded from Dokploy’s dashboard and from the SuperAdmin integration powered by the Dokploy API.
