Many Laravel deployments still use Supervisor to keep queue workers running. On systemd-based distros, you can let the init system do the job instead.
Why use systemd for Laravel workers?
- Already installed and managed by the OS
- Native logging with journalctl
- Restart policies and resource limits per service
You end up with fewer moving parts and simpler automation via systemctl.
Basic systemd unit for a queue worker
Create /etc/systemd/system/laravel-queue-worker.service
[Unit]
Description=Laravel Queue Worker
After=network.target
[Service]
User=www-data
Group=www-data
Restart=always
RestartSec=5
StartLimitIntervalSec=0
Environment=APP_ENV=production
Environment=APP_DEBUG=false
WorkingDirectory=/var/www/myapp/current
ExecStart=/usr/bin/php artisan queue:work --sleep=3 --tries=3 --max-time=3600
StandardOutput=append:/var/log/laravel-queue.log
StandardError=append:/var/log/laravel-queue-error.log
[Install]
WantedBy=multi-user.targetReload and restart:
sudo systemctl daemon-reload
sudo systemctl enable --now laravel-queue-worker.serviceCheck status and logs:
sudo systemctl status laravel-queue-worker.service
sudo journalctl -u laravel-queue-worker.service -fHandle deploys safely
During deploys you usually:
- Upate code
- Run migrations
- Restart workers
Create a simple service override to ensure workers restart correctly:
sudo systemctl edit laravel-queue-worker.serviceThen:
[Service]
ExecStop=/usr/bin/php artisan queue:restart
TimeoutStopSec=60Now systemctl restart triggers Laravel’s own graceful restart mechanism.
Example deploy hook:
ssh deploy@server << 'EOF'
cd /var/www/myapp/current
php artisan migrate --force
sudo systemctl restart laravel-queue-worker.service
EOFMultiple queues and priorities
You can run multiple units for different queues. For a high-priority emails queue:
/etc/systemd/system/laravel-queue-emails.service:
[Unit]
Description=Laravel Queue Worker (emails)
After=network.target
[Service]
User=www-data
Group=www-data
Restart=always
RestartSec=3
WorkingDirectory=/var/www/myapp/current
ExecStart=/usr/bin/php artisan queue:work --queue=emails --sleep=1 --tries=5
StandardOutput=append:/var/log/laravel-queue-emails.log
StandardError=append:/var/log/laravel-queue-emails-error.log
[Install]
WantedBy=multi-user.targetEnable it:
sudo systemctl enable --now laravel-queue-emails.serviceCommon mistakes and fixes
| Mistake | Fix |
|---|---|
Using php artisan queue:listen in systemd | Use queue:work. queue:listen is mainly for development and more resource heavy. |
Forgetting to set WorkingDirectory | Always set it to your app root so artisan finds .env and vendor. |
Running as root | Use the web user (often www-data) and ensure permissions on storage / bootstrap/cache are correct. |
Once configured, you get robust workers with first‑class OS integration and one less dependency to manage.
Leave a Reply