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 containingartisanand 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 tostorage/(often the Plesk subscription user, notroot)
Quick helpers:
- Find
APP_DIR:cd /var/www/vhosts && find . -maxdepth 4 -name artisan -print - Find
PHP_BIN:command -v phporls -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-reloadsudo systemctl enable --now parcelpilot-queue-default parcelpilot-queue-imports
Verify:
sudo systemctl status parcelpilot-queue-default --no-pagersudo systemctl status parcelpilot-queue-imports --no-pager
5) Logs + troubleshooting
View logs:
sudo journalctl -u parcelpilot-queue-default -n 200 --no-pagersudo journalctl -u parcelpilot-queue-imports -n 200 --no-pager
Common issues:
- Permission errors writing logs/cache/sessions: make sure
RUN_AS_USERcan write tostorage/andbootstrap/cache/. - Wrong PHP binary: use the same
PHP_BINyou run manually in production (Plesk often uses/opt/plesk/php/8.3/bin/php). - App path wrong:
WorkingDirectorymust be the folder that containsartisan.
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.