Setting Up Background Workers and Queues in .neo.yml

workers: runs a second process from the same image with its own container, restart policy, and health check.

5 min read

The shape

A worker shares the app's Docker image and environment variables, but runs a different command in its own container:

workers:
  queue:
    command: php artisan queue:work --tries=3 --max-time=3600
    restart: always

Neo names the container app-<appname>-worker-queue, joins it to the same network as the app, and gives it the same env vars — including anything set with neo env set, since a worker reads whatever the app reads.

Multiple workers

workers:
  queue-default:
    command: php artisan queue:work --queue=default
  queue-emails:
    command: php artisan queue:work --queue=emails --tries=1

Each key becomes an independently named, independently restarted container — a crash in one doesn't affect the other or the app.

Health checks for workers

workers:
  queue:
    command: node worker.js
    health_check: "pgrep -f worker.js"

Without this, Neo only knows the container is running, not that the process inside it is actually doing work. A simple pgrep or a custom script that checks a heartbeat file both work.

Per-environment overrides

workers:
  queue:
    command: php artisan queue:work --tries=3

environments:
  staging:
    workers:
      queue:
        command: php artisan queue:work --tries=1 --stop-when-empty

An environment's workers: block fully replaces the top-level one when present — useful for a staging worker that processes a queue once and exits, rather than running forever.

What workers are not for

A worker is a long-running process by definition — the same "must keep running" rule as command:. A one-off task belongs in release: instead.

Try it yourself — Neo is free, with every feature unlocked.

Get started free