ParcelPilot
Help

Queue workers (systemd)

This is the recommended setup for Ubuntu 24.04.

Use systemd to ensure Laravel queue workers automatically start on boot and restart if they crash.

This guide is designed to match the current production setup:

  • QUEUE_CONNECTION=database
  • Two workers:
    • --queue=default
    • --queue=imports

1) Confirm the exact worker commands

On the server, confirm the actual queue:work commands you want systemd to run:

  • ps aux | grep "artisan queue:work" | grep -v grep

You should see something similar to:

  • /opt/plesk/php/8.3/bin/php artisan queue:work database --queue=imports --sleep=5 --tries=3 --timeout=1900
  • /opt/plesk/php/8.3/bin/php artisan queue:work database --queue=default --sleep=3 --tries=3 --timeout=120

If you run long jobs (for example Magento legacy stock sync), increase --timeout accordingly.

2) Pick values for these placeholders

You need three values for the unit files below:

  • APP_DIR — the directory containing artisan and your .env (example: /var/www/vhosts/<domain>/httpdocs)
  • PHP_BIN — full path to the PHP binary (Plesk example: /opt/plesk/php/8.3/bin/php)
  • RUN_AS_USER / RUN_AS_GROUP — a user/group that can read the app, .env, and write to storage/ (often the Plesk subscription user, not root)

Quick helpers:

  • Find APP_DIR: cd /var/www/vhosts && find . -maxdepth 4 -name artisan -print
  • Find PHP_BIN: command -v php or ls -1 /opt/plesk/php/*/bin/php

3) Create the systemd unit files

Create two services:

A) Default queue worker

Create /etc/systemd/system/parcelpilot-queue-default.service:

[Unit]
Description=ParcelPilot queue worker (default)
After=network.target

[Service]
Type=simple
User=RUN_AS_USER
Group=RUN_AS_GROUP
WorkingDirectory=APP_DIR

ExecStart=PHP_BIN artisan queue:work database --queue=default --sleep=3 --tries=3 --timeout=120

Restart=always
RestartSec=5
KillSignal=SIGTERM
TimeoutStopSec=60

# If you need additional env vars beyond .env, uncomment and set:
# Environment=APP_ENV=production

[Install]
WantedBy=multi-user.target

B) Imports queue worker

Create /etc/systemd/system/parcelpilot-queue-imports.service:

[Unit]
Description=ParcelPilot queue worker (imports)
After=network.target

[Service]
Type=simple
User=RUN_AS_USER
Group=RUN_AS_GROUP
WorkingDirectory=APP_DIR

# Note: this worker may run long stock sync jobs; keep the worker timeout high.
# It must be >= the job's `$timeout`.
ExecStart=PHP_BIN artisan queue:work database --queue=imports --sleep=5 --tries=3 --timeout=1900

Restart=always
RestartSec=5
KillSignal=SIGTERM
TimeoutStopSec=60

[Install]
WantedBy=multi-user.target

Replace RUN_AS_USER, RUN_AS_GROUP, APP_DIR, and PHP_BIN.

4) Enable + start the services

  • sudo systemctl daemon-reload
  • sudo systemctl enable --now parcelpilot-queue-default parcelpilot-queue-imports

Verify:

  • sudo systemctl status parcelpilot-queue-default --no-pager
  • sudo systemctl status parcelpilot-queue-imports --no-pager

5) Logs + troubleshooting

View logs:

  • sudo journalctl -u parcelpilot-queue-default -n 200 --no-pager
  • sudo journalctl -u parcelpilot-queue-imports -n 200 --no-pager

Common issues:

  • Permission errors writing logs/cache/sessions: make sure RUN_AS_USER can write to storage/ and bootstrap/cache/.
  • Wrong PHP binary: use the same PHP_BIN you run manually in production (Plesk often uses /opt/plesk/php/8.3/bin/php).
  • App path wrong: WorkingDirectory must be the folder that contains artisan.

6) Deploy workflow note

After deploys, queue workers may need restarting to pick up new code.

Options:

  • Restart services: sudo systemctl restart parcelpilot-queue-default parcelpilot-queue-imports
  • Or, from the app directory: PHP_BIN artisan queue:restart

7) Confirm in-app heartbeats

If your System Status page includes the queue worker heartbeat widget, it should change to “recent/OK” shortly after the services start.