Laravel Supervisor: Menjaga Queue Worker Tetap Berjalan di Ubuntu
Apa Itu Supervisor?
Supervisor adalah process manager yang dapat digunakan untuk menjalankan dan memantau proses yang berjalan di background.
Dalam aplikasi Laravel, Supervisor sering digunakan untuk menjaga Queue Worker agar tetap aktif.
Tanpa Supervisor, kita mungkin menjalankan:
php artisan queue:work
secara manual melalui terminal.
Masalahnya, ketika terminal ditutup atau proses berhenti, Queue Worker juga ikut berhenti.
Dengan Supervisor:
Laravel
↓
Queue
↓
Supervisor
↓
Queue Worker
Supervisor akan memantau Worker dan dapat menjalankannya kembali jika proses berhenti.
Kenapa Laravel Queue Membutuhkan Supervisor?
Laravel Queue Worker adalah proses yang berjalan terus-menerus.
Misalnya:
php artisan queue:work redis
Worker akan terus menunggu Job:
Worker
↓
Menunggu Job
↓
Ambil Job
↓
Process
↓
Menunggu Job berikutnya
Berbeda dengan request HTTP yang selesai setelah response dikirim.
Karena Worker merupakan long-running process, production membutuhkan process manager.
Supervisor merupakan salah satu pilihan yang populer untuk kebutuhan tersebut.
Apa yang Terjadi Jika Tidak Menggunakan Supervisor?
Misalnya Anda menjalankan:
php artisan queue:work
melalui SSH.
Kemudian koneksi SSH terputus.
Worker bisa ikut berhenti.
Akibatnya:
User
↓
Laravel
↓
Dispatch Job
↓
Queue
↓
Worker tidak ada
↓
Job menumpuk
Misalnya:
jobs
├── Job 1
├── Job 2
├── Job 3
├── Job 4
└── Job 5
Tidak ada Worker yang mengambil Job tersebut.
Fungsi Supervisor untuk Laravel Queue
Supervisor memiliki beberapa fungsi penting.
Menjalankan Worker
Supervisor menjalankan:
php artisan queue:work
secara otomatis.
Menjaga Worker Tetap Berjalan
Jika Worker berhenti karena error atau proses lain, Supervisor dapat menjalankannya kembali.
Autostart
Ketika server Ubuntu reboot, Supervisor dapat menjalankan Worker kembali.
Restart Otomatis
Jika process mati, Supervisor dapat melakukan restart.
Menyimpan Log
Output Worker dapat diarahkan ke file log sehingga lebih mudah diperiksa.
Arsitektur Laravel Queue dengan Supervisor
Contoh sederhana:
Laravel
│
↓
Redis
│
↓
Queue Job
│
↓
Supervisor
│
┌─────────┴─────────┐
↓ ↓
Queue Worker 1 Queue Worker 2
│ │
└─────────┬─────────┘
↓
Process Job
Supervisor tidak menggantikan Laravel Queue.
Supervisor hanya bertugas mengelola proses Worker.
Supervisor vs Laravel Queue Worker
Keduanya memiliki fungsi yang berbeda.
Laravel Queue Worker:
php artisan queue:work
bertugas mengambil dan memproses Job.
Supervisor:
Supervisor
bertugas menjaga proses Worker tetap hidup.
Jadi:
Supervisor
↓
Menjaga
↓
Laravel Queue Worker
↓
Memproses
↓
Job
Install Supervisor di Ubuntu
Pada Ubuntu, install Supervisor menggunakan:
sudo apt update
Kemudian:
sudo apt install supervisor
Setelah selesai, cek service:
sudo systemctl status supervisor
Jika berjalan, biasanya terlihat:
Active: active (running)
Jika belum aktif:
sudo systemctl start supervisor
Agar Supervisor otomatis berjalan ketika server boot:
sudo systemctl enable supervisor
Pastikan Laravel Sudah Bisa Menjalankan Queue
Sebelum membuat konfigurasi Supervisor, sebaiknya pastikan Queue Worker dapat berjalan secara manual.
Masuk ke directory Laravel:
cd /var/www/example.com
Kemudian:
php artisan queue:work
Jika Worker berhasil berjalan, berarti Laravel dan Queue kemungkinan sudah dikonfigurasi dengan benar.
Hentikan dengan:
Ctrl + C
Setelah itu baru pindahkan pengelolaannya ke Supervisor.
Jika Menggunakan Redis
Misalnya .env:
QUEUE_CONNECTION=redis
Worker dapat dijalankan:
php artisan queue:work redis
Jika menggunakan Queue tertentu:
php artisan queue:work redis --queue=default
Supervisor nantinya akan menjalankan command tersebut secara otomatis.
Membuat Konfigurasi Supervisor
File konfigurasi Supervisor biasanya berada di:
/etc/supervisor/conf.d/
Buat file:
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
Contoh konfigurasi:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/example.com/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/example.com/storage/logs/worker.log
stopwaitsecs=3600
Sesuaikan:
/var/www/example.com
dengan directory project Laravel Anda.
Penjelasan program
Bagian:
[program:laravel-worker]
adalah nama program yang dikelola Supervisor.
Nama ini nantinya digunakan ketika menjalankan:
sudo supervisorctl status
atau:
sudo supervisorctl restart laravel-worker
Penjelasan process_name
Contoh:
process_name=%(program_name)s_%(process_num)02d
Ini menentukan nama process ketika kita menggunakan lebih dari satu Worker.
Misalnya:
numprocs=3
maka bisa muncul:
laravel-worker_00
laravel-worker_01
laravel-worker_02
Ini berguna ketika aplikasi membutuhkan beberapa Worker paralel.
Penjelasan command
Bagian terpenting adalah:
command=php /var/www/example.com/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
Supervisor akan menjalankan command tersebut.
Secara manual, command-nya sama dengan:
php artisan queue:work redis --sleep=3 --tries=3 --timeout=90
Perbedaannya adalah Supervisor yang menjalankannya dan memantaunya.
Gunakan Absolute Path untuk PHP
Pada production, lebih aman mengetahui path PHP yang digunakan.
Cek:
which php
Misalnya hasil:
/usr/bin/php
Maka konfigurasi dapat ditulis:
command=/usr/bin/php /var/www/example.com/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
Ini membantu menghindari masalah ketika environment CLI Supervisor berbeda dengan terminal SSH.
Cek Versi PHP
Jalankan:
php -v
Pastikan PHP yang digunakan Supervisor sesuai dengan PHP yang digunakan aplikasi.
Misalnya:
PHP 8.3
Jika terminal menggunakan PHP 8.3 tetapi Supervisor menggunakan PHP 8.1, Worker bisa gagal karena dependency aplikasi membutuhkan PHP 8.3.
Penjelasan autostart
autostart=true
Artinya Supervisor akan menjalankan Worker secara otomatis ketika Supervisor dijalankan.
Ini penting setelah VPS reboot.
Alurnya:
Ubuntu Reboot
↓
Supervisor Start
↓
Laravel Worker Start
↓
Queue Ready
Penjelasan autorestart
autorestart=true
Supervisor akan mencoba menjalankan kembali Worker ketika proses berhenti.
Misalnya:
Worker
↓
Crash
↓
Supervisor mendeteksi
↓
Worker restart
Ini merupakan salah satu alasan utama menggunakan Supervisor.
Penjelasan user
Contoh:
user=www-data
Artinya Worker dijalankan sebagai user www-data.
Pastikan user tersebut memiliki akses yang diperlukan terhadap project Laravel.
Misalnya:
storage/
bootstrap/cache/
vendor/
Jika aplikasi menggunakan user lain, sesuaikan konfigurasi.
Jangan Asal Menggunakan root
Hindari menjalankan Queue Worker sebagai:
user=root
kecuali memang ada alasan khusus dan Anda memahami konsekuensinya.
Lebih baik menggunakan user aplikasi seperti:
www-data
atau user deployment yang memang dirancang untuk menjalankan aplikasi.
Penjelasan numprocs
numprocs=1
berarti satu process Worker.
Jika:
numprocs=4
Supervisor akan menjalankan empat Worker.
Konsepnya:
Supervisor
├── Worker 1
├── Worker 2
├── Worker 3
└── Worker 4
Ini dapat meningkatkan throughput Queue jika server memiliki resource yang cukup.
Jangan Langsung Menggunakan Banyak Worker
Misalnya VPS hanya memiliki:
2 CPU
2 GB RAM
jangan langsung:
numprocs=10
Lebih banyak Worker berarti lebih banyak proses PHP yang dapat berjalan bersamaan.
Perhatikan:
CPU
RAM
Database
Redis
API eksternal
Tambahkan Worker secara bertahap berdasarkan hasil monitoring.
Penjelasan stdout_logfile
Contoh:
stdout_logfile=/var/www/example.com/storage/logs/worker.log
Output Worker akan diarahkan ke file tersebut.
Kemudian kita dapat melihatnya:
tail -f /var/www/example.com/storage/logs/worker.log
Ini sangat membantu ketika Worker tidak berjalan sesuai harapan.
Penjelasan redirect_stderr
redirect_stderr=true
Error output juga diarahkan ke log yang sama.
Dengan begitu, output dan error Worker lebih mudah diperiksa dari satu tempat.
Penjelasan stopwaitsecs
Contoh:
stopwaitsecs=3600
Ini penting untuk Job yang membutuhkan waktu cukup lama.
Misalnya Job:
Generate laporan besar
↓
Proses 10 menit
Supervisor perlu memberi waktu yang cukup ketika menghentikan Worker.
Nilainya harus disesuaikan dengan durasi maksimum Job dan strategi deployment Anda.
Setelah Membuat Konfigurasi
Setelah file:
/etc/supervisor/conf.d/laravel-worker.conf
dibuat, jalankan:
sudo supervisorctl reread
Kemudian:
sudo supervisorctl update
Supervisor akan membaca konfigurasi baru.
Cek Status Worker
Jalankan:
sudo supervisorctl status
Jika berhasil:
laravel-worker RUNNING
Jika menggunakan beberapa process:
laravel-worker:laravel-worker_00 RUNNING
laravel-worker:laravel-worker_01 RUNNING
Status RUNNING berarti Supervisor sedang menjalankan proses tersebut.
Restart Worker
Jika konfigurasi sudah berubah:
sudo supervisorctl restart laravel-worker:*
Atau jika hanya satu process:
sudo supervisorctl restart laravel-worker
Kemudian:
sudo supervisorctl status
Stop Worker
Untuk menghentikan:
sudo supervisorctl stop laravel-worker:*
Untuk menjalankan kembali:
sudo supervisorctl start laravel-worker:*
Cek Apakah Job Diproses
Setelah Worker berjalan, dispatch sebuah Job.
Misalnya:
SendWelcomeEmail::dispatch($user);
Kemudian lihat status Queue.
Jika menggunakan Redis, periksa melalui Horizon atau monitoring Queue yang tersedia.
Jika Job selesai, berarti:
Laravel
↓
Redis
↓
Supervisor
↓
Worker
↓
Job
sudah berjalan.
Supervisor Tidak Menjamin Job Tidak Gagal
Ini penting.
Supervisor menjaga process Worker, bukan isi Job.
Misalnya:
Supervisor: RUNNING
Worker: RUNNING
Job: FAILED
Ini tetap mungkin terjadi.
Contohnya Job memiliki:
$order->payment()->process();
dan API pembayaran gagal.
Supervisor tidak memperbaiki logic tersebut.
Jadi bedakan:
Worker tidak berjalan
dengan:
Worker berjalan tetapi Job gagal
Cara Mengetahui Worker Benar-Benar Berjalan
Jalankan:
sudo supervisorctl status
Kemudian:
ps aux | grep "queue:work"
Anda dapat melihat process PHP yang menjalankan Queue Worker.
Jika menggunakan Horizon:
ps aux | grep horizon
Namun untuk monitoring sehari-hari, status Supervisor dan dashboard Queue biasanya lebih praktis.
Melihat Log Worker
Jika menggunakan:
stdout_logfile=/var/www/example.com/storage/logs/worker.log
jalankan:
tail -f /var/www/example.com/storage/logs/worker.log
Untuk melihat beberapa baris terakhir:
tail -n 100 /var/www/example.com/storage/logs/worker.log
Jika Worker terus restart, log ini sangat berguna.
Supervisor FATAL
Jika:
sudo supervisorctl status
menghasilkan:
laravel-worker FATAL
jangan langsung mengubah konfigurasi.
Cek command secara manual:
cd /var/www/example.com
php artisan queue:work redis
Jika muncul error:
Class not found
atau:
RedisException
atau:
Permission denied
itulah petunjuk utama.
Cek Log Supervisor
Supervisor memiliki log sendiri.
Lokasi dapat berbeda tergantung konfigurasi, tetapi salah satu lokasi yang umum:
sudo tail -f /var/log/supervisor/supervisord.log
Perhatikan pesan seperti:
spawn error
permission denied
can't find command
exited too quickly
Pesan tersebut biasanya membantu menemukan kesalahan konfigurasi.
Masalah command not found
Misalnya Supervisor menghasilkan:
can't find command 'php'
Padahal ketika SSH:
php -v
berhasil.
Ini bisa terjadi karena environment PATH Supervisor berbeda.
Gunakan absolute path:
command=/usr/bin/php /var/www/example.com/artisan queue:work redis
Cari path dengan:
which php
Masalah Permission
Misalnya log:
Permission denied
Periksa owner project:
ls -la /var/www/example.com
Periksa:
ls -la /var/www/example.com/storage
Pastikan user Supervisor:
user=www-data
memiliki akses yang diperlukan.
Untuk Laravel, directory yang biasanya perlu write adalah:
storage/
bootstrap/cache/
Masalah storage/logs
Jika konfigurasi:
stdout_logfile=/var/www/example.com/storage/logs/worker.log
tetapi directory tersebut tidak dapat ditulis oleh user Worker, Worker bisa mengalami masalah.
Pastikan directory tersedia:
ls -la /var/www/example.com/storage/logs
Dan permission-nya sesuai dengan user aplikasi.
Queue Worker Mati Setelah Beberapa Saat
Jika Worker:
RUNNING
kemudian:
STOPPED
periksa:
Job timeout
Memory limit
PHP fatal error
Redis connection
Database connection
Supervisor hanya dapat restart process setelah process tersebut berhenti.
Ia tidak otomatis memperbaiki penyebab process berhenti.
Gunakan --timeout dengan Benar
Contoh:
php artisan queue:work redis --timeout=90
Artinya Worker memiliki batas waktu untuk Job sesuai konfigurasi tersebut.
Jangan membuat:
Job timeout
dan:
stopwaitsecs
tidak selaras.
Untuk Job yang lama, perhatikan juga konfigurasi timeout pada:
Queue
Supervisor
PHP
External API
Semua harus dirancang dengan benar.
Worker Tidak Mengambil Job
Jika Supervisor menunjukkan:
RUNNING
tetapi Job tetap menumpuk, periksa:
QUEUE_CONNECTION
Redis
Queue name
Worker command
Job delay
Job availability
Contoh Worker:
command=php /var/www/example.com/artisan queue:work redis --queue=emails
tetapi Job dikirim ke:
->onQueue('notifications')
Worker tidak akan mengambil Job tersebut.
Gunakan Queue yang Sesuai
Misalnya aplikasi memiliki:
high
default
low
Worker dapat dikonfigurasi:
command=php /var/www/example.com/artisan queue:work redis --queue=high,default,low
Namun jika prioritas sangat penting, sebaiknya desain Worker dan Queue dengan jelas.
Contoh:
Worker High Priority
↓
high
Worker Default
↓
default
Worker Low Priority
↓
low
Arsitektur ini dapat memberikan kontrol lebih baik ketika workload meningkat.
Supervisor untuk Laravel Horizon
Jika menggunakan Laravel Horizon, Supervisor dapat menjalankan:
command=php /var/www/example.com/artisan horizon
Bukan:
command=php /var/www/example.com/artisan queue:work
Contoh:
[program:laravel-horizon]
process_name=%(program_name)s
command=/usr/bin/php /var/www/example.com/artisan horizon
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/example.com/storage/logs/horizon.log
stopwaitsecs=3600
Jadi pilih salah satu pendekatan sesuai arsitektur aplikasi:
Supervisor
↓
queue:work
atau:
Supervisor
↓
Horizon
↓
Workers
Supervisor vs Horizon
Keduanya bukan pengganti satu sama lain.
Supervisor:
Process Manager
Horizon:
Laravel Queue Manager + Monitoring
Dalam setup tertentu, keduanya digunakan bersama:
Supervisor
↓
Horizon
↓
Redis
↓
Queue Workers
Sedangkan untuk Queue biasa:
Supervisor
↓
queue:work
↓
Redis
Berapa Jumlah Worker yang Sebaiknya Digunakan?
Tidak ada angka universal.
Mulailah dari:
numprocs=1
Kemudian monitor.
Jika Queue backlog meningkat:
Job masuk
↓
Job selesai lebih lambat
↓
Queue backlog meningkat
Anda dapat mempertimbangkan menambah Worker.
Misalnya:
numprocs=2
kemudian:
CPU
RAM
Database
Redis
dipantau kembali.
Lebih Banyak Worker Tidak Selalu Lebih Cepat
Misalnya Job melakukan query database berat:
Worker 1 → DB
Worker 2 → DB
Worker 3 → DB
Worker 4 → DB
Worker 5 → DB
Worker 6 → DB
Database bisa menjadi bottleneck.
Akibatnya:
Worker ↑
↓
DB load ↑
↓
Query semakin lambat
↓
Job semakin lambat
Karena itu scaling Worker harus dilakukan berdasarkan bottleneck yang sebenarnya.
Gunakan Supervisor untuk Production, Bukan Development
Untuk development lokal, Anda mungkin cukup menjalankan:
php artisan queue:work
Tetapi pada production VPS, proses harus tetap hidup setelah:
- SSH disconnect
- Terminal ditutup
- VPS reboot
- Worker crash
Supervisor sangat berguna untuk kebutuhan tersebut.
Contoh Konfigurasi Production yang Praktis
Misalnya aplikasi:
/var/www/myapp
menggunakan Redis.
File:
/etc/supervisor/conf.d/myapp-worker.conf
isi:
[program:myapp-worker]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/php /var/www/myapp/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/myapp/storage/logs/worker.log
stopwaitsecs=3600
Kemudian:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status
Hasilnya kira-kira:
myapp-worker:myapp-worker_00 RUNNING
myapp-worker:myapp-worker_01 RUNNING
Checklist Setelah Setup
Setelah konfigurasi Supervisor selesai, cek:
sudo systemctl status supervisor
Kemudian:
sudo supervisorctl status
Pastikan Worker:
RUNNING
Tes manual:
cd /var/www/myapp
php artisan queue:work redis
Pastikan tidak ada error.
Kemudian dispatch Job.
Periksa:
Job diproses?
Log muncul?
Worker tetap RUNNING?
Setelah itu reboot server jika ingin menguji autostart:
sudo reboot
Setelah VPS kembali:
sudo supervisorctl status
Worker seharusnya kembali berjalan.
Troubleshooting Cepat
| Masalah | Yang Dicek |
|---|---|
| Worker tidak start | command, PHP path, permission |
Supervisor FATAL | Log Supervisor |
| Worker langsung mati | Jalankan queue:work manual |
| Worker tidak mengambil Job | Queue connection dan queue name |
| Job terus gagal | Laravel log dan failed jobs |
| Setelah reboot Worker mati | autostart dan service Supervisor |
php: command not found | Gunakan absolute path PHP |
| Permission denied | User Supervisor dan ownership |
| Worker kehabisan memory | Jumlah Worker dan memory Job |
| Job terlalu lama | --timeout dan stopwaitsecs |
| Redis error | Redis service dan .env |
| Horizon tidak berjalan | Jalankan Horizon manual dan cek Supervisor |
Kesalahan yang Sering Terjadi
Menjalankan Worker Melalui SSH
php artisan queue:work
lalu menganggap Queue akan terus berjalan.
Untuk production, gunakan process manager.
Tidak Menggunakan Absolute Path
Supervisor bisa memiliki environment berbeda dengan shell SSH.
Menjalankan Terlalu Banyak Worker
Resource VPS dan database bisa habis.
Mengabaikan Log
Ketika Worker berhenti, log biasanya memberikan petunjuk paling penting.
Menggunakan root
Gunakan user aplikasi yang sesuai.
Tidak Restart Worker Setelah Deployment
Worker adalah long-running process dan dapat tetap menggunakan code yang sebelumnya dimuat.
Gunakan mekanisme restart yang sesuai, misalnya:
php artisan queue:restart
atau, jika menggunakan Horizon:
php artisan horizon:terminate
Supervisor kemudian dapat menjalankan kembali process tersebut.
Supervisor dan queue:restart
Laravel menyediakan:
php artisan queue:restart
Command ini memberi sinyal kepada Queue Worker agar berhenti setelah menyelesaikan Job yang sedang berjalan.
Jika Supervisor menggunakan:
autorestart=true
Supervisor akan melihat Worker berhenti dan menjalankannya kembali.
Alurnya:
queue:restart
↓
Worker menyelesaikan Job
↓
Worker berhenti
↓
Supervisor mendeteksi
↓
Worker baru dijalankan
Ini berguna ketika melakukan deployment.
Bedakan queue:restart dan supervisorctl restart
queue:restart memberi tahu Laravel Worker untuk melakukan restart secara graceful.
Sedangkan:
sudo supervisorctl restart laravel-worker
memerintahkan Supervisor untuk menghentikan dan menjalankan kembali process.
Untuk deployment, pilih metode yang sesuai dengan kebutuhan dan karakteristik Job Anda.
Alur Deployment yang Lebih Aman
Contoh sederhana:
Deploy Code
↓
composer install
↓
Update konfigurasi
↓
Database migration
↓
Restart Queue Worker
↓
Supervisor menjalankan Worker baru
Untuk Queue Worker biasa:
php artisan queue:restart
Untuk Horizon:
php artisan horizon:terminate
Pastikan deployment tidak menyebabkan Job yang sedang berjalan terputus secara tidak aman.
Kesimpulan
Supervisor merupakan solusi praktis untuk menjaga Laravel Queue Worker tetap berjalan di Ubuntu VPS.
Tanpa Supervisor:
SSH
↓
queue:work
↓
Terminal ditutup
↓
Worker berhenti
Dengan Supervisor:
Ubuntu
↓
Supervisor
↓
Queue Worker
↓
Queue
Jika Worker berhenti:
Worker crash
↓
Supervisor
↓
Restart
↓
Worker kembali aktif
Setup dasar yang perlu diperhatikan adalah:
1. Install Supervisor
2. Pastikan Queue Worker berjalan manual
3. Buat konfigurasi Supervisor
4. Gunakan absolute path PHP
5. Tentukan user yang tepat
6. Atur autostart dan autorestart
7. Simpan log Worker
8. Jalankan supervisorctl reread
9. Jalankan supervisorctl update
10. Cek status Worker
Untuk aplikasi Laravel sederhana yang menggunakan Redis:
Laravel
↓
Redis
↓
Supervisor
↓
Queue Worker
Sedangkan jika menggunakan Laravel Horizon:
Laravel
↓
Redis
↓
Supervisor
↓
Horizon
↓
Queue Workers
Kuncinya bukan sekadar membuat Worker berstatus RUNNING, tetapi memastikan Worker, Queue backend, resource server, dan deployment berjalan sebagai satu sistem.
Dengan konfigurasi Supervisor yang benar, Queue Worker dapat tetap berjalan setelah SSH terputus, melakukan restart ketika process berhenti, dan otomatis aktif kembali setelah Ubuntu VPS melakukan reboot.

