Skip to content

Docker / Compose

Docker / Compose

Run the autoscaler in its own container, alongside your web and scheduler containers.

  • Single-host mode: exactly one autoscaler container per app.
  • Cluster mode: one autoscaler replica per host/pod is supported, provided Redis-backed cluster mode is enabled.

docker-compose.yml

services:
  app:
    # your main Laravel web container
    image: your-app:latest
    # ...

  queue-autoscale:
    image: your-app:latest
    command: php artisan queue:autoscale
    restart: unless-stopped
    depends_on:
      - redis
    environment:
      # Same env as your app — REDIS_*, DB_*, APP_KEY, etc.
      - APP_ENV=production
    # Let the manager shut down cleanly before Docker kills the container.
    # Must be >= queue-autoscale.workers.shutdown_timeout_seconds (default 30).
    stop_grace_period: 60s
    # Forward signals to PID 1 so SIGTERM reaches PHP, not /bin/sh.
    init: true

init: true matters. Without it, php artisan runs as PID 1 via the shell, which Docker cannot signal cleanly — you'd get abrupt kills and orphaned queue:work children.

Dockerfile considerations

If your base image uses a CMD wrapper, override it with exec form so signals forward correctly:

# This is what your main app image already does, but shown for the autoscale container:
CMD ["php", "artisan", "queue:autoscale"]

Avoid shell form (CMD php artisan queue:autoscale) because it spawns a shell that swallows signals.

Replica count

For Docker Swarm:

services:
  queue-autoscale:
    # ...
    deploy:
      replicas: 1 # single-host mode
      restart_policy:
        condition: any

For Kubernetes single-host mode, a Deployment with replicas: 1 plus strategy.type: Recreate avoids two autoscalers running simultaneously during rollouts:

spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    spec:
      containers:
        - name: queue-autoscale
          command: ["php", "artisan", "queue:autoscale"]
          terminationGracePeriodSeconds: 60

For cluster mode, multiple replicas are valid. Each replica still runs exactly one local queue:autoscale process, and cluster coordination happens through Redis.

For cluster mode, multiple replicas are valid. Each replica still runs exactly one local queue:autoscale process, and cluster coordination happens through Redis.

Zero-downtime deploys

With Compose, docker compose up -d queue-autoscale stops the current container (SIGTERM, graceful shutdown, new workers spawned by old manager exit cleanly) and starts the new one (which picks up current state from Redis — no warm-up gap).

Logs

The manager writes to stdout/stderr by default. Ship them to your log aggregator:

logging:
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"

Or point at Loki/Fluent/CloudWatch via logging.driver.

Sanity check

docker compose logs -f queue-autoscale

Should show Autoscale manager started within a second, then worker-spawn activity as soon as jobs arrive.