Chapter 05

Background work

Queue workers, a scheduler, and one-shot startup tasks. There is no switch for these in the panel — you declare them as files in your own folder, which means they travel with your code.

Queue workers & scheduler are PHP-image only

The queue worker and scheduler need PHP, so they run on the Laravel image. The static (web-base) image does run a process supervisor, but the only file it honours is boot.conf — a one-shot startup task; queue-worker.conf and scheduler.conf do not apply there.

Three filenames

Create a directory .nimbus/supervisor/ at the root of your app and put program definitions in it. Because these ship in your repo, they land at <folder>/application/.nimbus/supervisor/. The image honours exactly three filenames — nothing else is read.

FilePurpose
boot.confRuns once when the container starts, then exits. Use it for warm-ups or one-time setup.
queue-worker.confLong-running queue workers, kept alive and restarted if they die.
scheduler.confThe task scheduler.

The rule is simply presence: the file exists, the program runs. Delete it, and it stops. There is no state stored anywhere in the panel and nothing to toggle.

Other filenames are ignored in silence

There is no wildcard matching. A file named worker.conf or queue-worker.conf.bak is never loaded — and never warned about either. If a program is not running, check the filename first, character by character.

This is deliberate: a stray or planted .conf in a web-accessible folder must never become a running process.

What a definition looks like

These are supervisor program definitions. The image supplies no defaults, so each file must be complete on its own:

[program:queue-worker]
command=/usr/bin/php /var/www/virtual/app.example.com/application/artisan queue:work --sleep=3 --tries=3
directory=/var/www/virtual/app.example.com/application
user=www-data
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

Use absolute paths in command. Because your folder is mounted at the identical path inside the container, the literal site path is correct in both places — no guesswork about what the path looks like from the inside.

Log to /dev/stdout and /dev/stderr as above. Everything the container prints is collected together, so your worker output lands beside nginx and PHP errors instead of in a file nobody reads.

The rules your file must satisfy

Every file is validated at container start. The checks are few and strict:

  1. It must parse as INI. A syntax error means the file is rejected.
  2. Only program sections are allowed[program:…], [group:…] or [eventlistener:…]. You cannot redefine the supervisor daemon itself.
  3. Programs run as www-data. Leave user= out and it is filled in for you. Set it to anything else and the file is rejected outright rather than quietly rewritten.

A rejected file is skipped, never fatal. The reason is printed to the container log and the rest of the site carries on serving. This matters: supervisor aborts on a bad config, so an unvalidated file would take nginx and PHP down with it and the site would go completely dark. One broken worker definition costs you that worker, not the site.

Making a change take effect

Programs are read at container start. Adding, editing or deleting a file does nothing until then. Restart the site from the panel — the same restart that clears the opcache after a deploy, so a deploy that adds a worker needs only the one restart.

Recreating the container for a settings change, or switching image, also re-reads them. None of those operations ever modify or remove your .nimbus/ directory.

Checking whether a program loaded

On start, the container logs one line listing which programs it loaded, and a separate SKIPPED line with the reason for each file it rejected. That log line is the fastest way to tell "my file has a typo in the name" from "my file has a typo inside it". Reading it needs log access from the box.

You cannot manage these programs from inside the container — the supervisor control socket is restricted to root, and your shell is not. Restarting the site is the supported way to apply a change.