Laravel Queue Workers Stop Running on Shared VPS: 7 Hidden cPanel Permission and PHP‑FPM Bugs That Crash Your Jobs Overnight and How to Fix Them Now
Feeling the sting of dead queue jobs at 2 a.m.? You’re not alone. Every Laravel developer who’s ever deployed to a cheap shared VPS knows the nightmare of workers disappearing, emails piling up, and customers complaining. The cause is rarely “bad code”—it’s usually a silent permission or PHP‑FPM mis‑config that lives under cPanel’s radar.
Why This Matters
Queue workers are the heart of any modern SaaS or WordPress‑integrated Laravel app. When they stop, order processing, notification delivery, and API syncs grind to a halt. In a production environment this translates directly to lost revenue, angry users, and a bruised reputation.
Common Causes on Shared VPS
- Incorrect
user/groupownership on/var/wwwafter Composer install. - cPanel “Allow Override” disabled for
.htaccesscausing PHP‑FPM pool limits to be ignored. - PHP‑FPM
pm.max_childrenset too low for burst traffic. - Supervisor service files not executable by the
nobodyuser. - SELinux/AppArmor policies blocking socket communication with Redis.
- Missing
php-fpmreload aftercomposer dump‑autoloadon shared servers. - cPanel cron restrictions that silently kill long‑running
queue:workprocesses.
Step‑by‑Step Fix Tutorial
1. Verify File Permissions
# From the SSH console
cd /home/username/public_html
sudo chown -R username:username .
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;
Tip: Replace username with the actual cPanel user. On most shared VPS this fixes the “Permission denied” errors logged by Laravel.
2. Adjust PHP‑FPM Pool Settings
# /opt/cpanel/usr/var/php-fpm/pools/username.conf
[username]
user = username
group = username
listen = /opt/cpanel/ea-php81/root/usr/var/run/php-fpm/username.sock
pm = dynamic
pm.max_children = 12
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 5000
Warning: Setting pm.max_children too high on a low‑RAM VPS will trigger OOM kills. Start with 12 and monitor free -m.
3. Re‑create Supervisor Config with Correct Owner
# /etc/supervisor/conf.d/laravel-queue.conf
[program:laravel-queue]
process_name=%(program_name)s_%(process_num)02d
command=php /home/username/public_html/artisan queue:work --sleep=3 --tries=3 --timeout=60
autostart=true
autorestart=true
user=username
numprocs=2
redirect_stderr=true
stdout_logfile=/home/username/logs/queue.log
stopwaitsecs=3600
Success: After running supervisorctl reread && supervisorctl update, your workers stay alive across reboots.
4. Enable cPanel .htaccess Overrides for PHP‑FPM
# Add to .htaccess in the Laravel root
suPHP_ConfigPath /opt/cpanel/ea-php81/root/etc/php.ini
# Ensure AllowOverride All in Apache conf (ask your host if you can edit)
5. Open Redis Socket for the cPanel User
# /etc/redis/redis.conf
unixsocket /var/run/redis/redis.sock
unixsocketperm 770
# Add the cPanel user to the redis group
sudo usermod -aG redis username
6. Reload All Services
sudo systemctl restart php-fpm
sudo systemctl restart supervisor
sudo systemctl restart redis
VPS or Shared Hosting Optimization Tips
- Prefer PHP 8.2 on Ubuntu 22.04 LTS for better JIT performance.
- Use Redis queue driver instead of database for high‑throughput jobs.
- Enable opcache.validate_timestamps=0 in
php.inifor production. - Set MySQL
innodb_flush_log_at_trx_commit=2for write‑heavy queues. - Deploy a tiny Docker‑compose stack locally to mirror the shared environment.
Real World Production Example
Acme SaaS runs a Laravel API gateway on a 2 CPU, 4 GB shared VPS. After applying the seven fixes, their queue:work processes went from crashing at 02:13 AM to a 99.9 % success rate over a 30‑day window.
Before vs After Results
| Metric | Before | After |
|---|---|---|
| Queue crashes per day | 7‑9 | 0‑1 |
| Avg job latency | 5.2 s | 1.1 s |
| CPU usage (peak) | 95 % | 68 % |
Security Considerations
- Never run queue workers as
root—use the cPanel user. - Restrict Redis socket permissions to the
redisgroup only. - Enable
disable_functions=exec,shell_execinphp.inifor shared‑hosting accounts. - Use
fail2banto block repeated SSH brute‑force attempts that could hijack your queue processes.
Bonus Performance Tips
- Switch to
queue:listenonly during development;queue:work --daemonis faster in production. - Set
QUEUE_CONNECTION=redisandREDIS_CLIENT=phpredisfor native socket speed. - Leverage Laravel Horizon on a separate VPS for visual monitoring.
- Run
composer install --optimize-autoloader --no-devbefore each deploy.
FAQ
Q: My shared host disables Supervisor. What can I do?
A: Use cPanel’s “Cron Jobs” to run
php artisan queue:work --daemonwith--sleep=3and--tries=3. Combine withnohupand&to keep it alive.
Q: Will increasing
pm.max_childrenaffect other sites on the same VPS?A: Yes. Always monitor total RAM usage and adjust per‑site limits accordingly.
Final Thoughts
Queue workers crashing on a shared VPS is rarely a Laravel bug; it’s a server‑side permission or PHP‑FPM mis‑tune. By addressing the seven hidden issues above, you turn a night‑time disaster into a reliable, scalable background processor. Apply the steps, monitor logs, and your SaaS or WordPress‑integrated app will stay alive 24/7.
💡 Ready to upgrade? If you need a cheap, secure VPS that gives you full root access and unlimited SSH, check out Hostinger’s plans. They provide the flexibility to avoid cPanel restrictions altogether.
No comments:
Post a Comment