Setup Supervisor untuk Queue Laravel di Production

Supervisor dipakai agar queue worker Laravel tetap berjalan di server production. Jawaban cepatnya: buat konfigurasi program Supervisor yang menjalankan php artisan queue:work, arahkan ke folder project, jalankan dengan user web/deploy yang benar, lalu aktifkan lewat supervisorctl reread, update, dan start.

Queue worker tidak cukup dijalankan manual dari terminal karena prosesnya akan berhenti saat terminal ditutup, server restart, atau proses crash. Supervisor menjaga worker tetap hidup dan bisa otomatis menjalankannya lagi.

Kapan Laravel Membutuhkan Queue?

Queue berguna untuk pekerjaan yang tidak harus selesai saat itu juga, misalnya:

  • mengirim email setelah user registrasi
  • memproses upload gambar
  • export laporan besar
  • import data CSV
  • mengirim notifikasi
  • memanggil API eksternal yang lambat

Tanpa queue, user harus menunggu pekerjaan itu selesai di request utama. Dengan queue, request bisa cepat selesai, lalu worker memproses job di belakang.

Cara Kerja Queue Worker

Alurnya sederhana:

Controller
  -> dispatch job
  -> job masuk queue
  -> queue worker mengambil job
  -> job diproses

Di Laravel, worker biasanya dijalankan dengan:

php artisan queue:work

Di production, perintah ini harus dikelola Supervisor.

Siapkan Konfigurasi Queue

Contoh .env sederhana:

QUEUE_CONNECTION=database

Untuk queue berbasis database, buat tabel queue:

php artisan queue:table
php artisan migrate

Jika memakai Redis:

QUEUE_CONNECTION=redis

Pilih satu driver yang sesuai dengan project. Untuk pemula, database queue cukup untuk belajar dan aplikasi kecil. Untuk traffic lebih tinggi, Redis biasanya lebih cocok.

Contoh Job Laravel

Buat job:

php artisan make:job KirimEmailInvoice

Contoh isi job:

<?php

namespace App\Jobs;

use App\Mail\InvoiceDibuat;
use App\Models\Invoice;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;

class KirimEmailInvoice implements ShouldQueue
{
    use Queueable;

    public function __construct(public Invoice $invoice)
    {
    }

    public function handle(): void
    {
        Mail::to($this->invoice->user->email)
            ->send(new InvoiceDibuat($this->invoice));
    }
}

Dispatch dari controller:

<?php

use App\Jobs\KirimEmailInvoice;

KirimEmailInvoice::dispatch($invoice);

Kalau tidak ada worker, job akan masuk antrean tetapi tidak pernah diproses.

Install dan Cek Supervisor

Di server Ubuntu/Debian, Supervisor biasanya bisa dipasang dengan:

sudo apt update
sudo apt install supervisor
sudo systemctl enable supervisor
sudo systemctl start supervisor

Cek status:

sudo systemctl status supervisor

Konfigurasi Supervisor untuk Laravel

Buat file:

sudo nano /etc/supervisor/conf.d/toko-laravel-worker.conf

Isi contoh:

[program:toko-laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/toko-laravel/artisan queue:work --sleep=3 --tries=3 --max-time=3600
directory=/var/www/toko-laravel
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/toko-laravel/storage/logs/worker.log
stopwaitsecs=3600

Aktifkan:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start toko-laravel-worker:*
sudo supervisorctl status

Kalau status RUNNING, worker sudah hidup.

Restart Worker Setelah Deploy

Setelah deploy kode baru, jalankan:

php artisan queue:restart

Perintah ini memberi sinyal agar worker berhenti setelah job saat ini selesai. Supervisor akan menjalankannya lagi dengan kode terbaru.

Tambahkan ke checklist deploy setelah composer install, migration, build asset, dan cache config. Jika project juga punya pekerjaan terjadwal, aktifkan Scheduler Laravel di Production lewat cron.

Membaca Log Queue

Jika job gagal, cek:

php artisan queue:failed
tail -f storage/logs/laravel.log
tail -f storage/logs/worker.log

Untuk mencoba ulang job gagal:

php artisan queue:retry all

Untuk menghapus daftar job gagal setelah ditangani:

php artisan queue:flush

Jangan langsung flush sebelum membaca error, karena daftar failed job membantu diagnosis.

Kesalahan yang Sering Terjadi

Menjalankan Worker Manual dari SSH

Perintah manual seperti ini akan mati saat sesi SSH ditutup:

php artisan queue:work

Gunakan Supervisor untuk production.

Lupa queue:restart Setelah Deploy

Worker yang sudah lama hidup bisa masih memakai kode lama. Setelah deploy, jalankan:

php artisan queue:restart

User Supervisor Tidak Punya Permission

Jika user=www-data, pastikan user itu bisa membaca project dan menulis log. Error permission sering muncul di storage/logs.

numprocs Terlalu Besar

Worker terlalu banyak bisa membebani database atau API eksternal. Mulai dari numprocs=1 atau 2, lalu naikkan jika benar-benar perlu.

Tidak Membatasi Retry

Gunakan --tries=3 atau kebijakan retry yang jelas. Job yang selalu gagal tidak boleh diproses tanpa batas.

Pencegahan

  1. Pakai nama program Supervisor yang jelas.
  2. Simpan log worker di storage/logs.
  3. Jalankan queue:restart setiap deploy.
  4. Pantau queue:failed.
  5. Buat job idempotent jika memungkinkan, agar aman saat retry.
  6. Jangan masukkan pekerjaan berat ke request utama.

Bacaan Terkait

FAQ

Apa bedanya queue worker dan scheduler?

Queue worker memproses job antrean. Scheduler menjalankan command terjadwal, misalnya setiap menit atau setiap hari.

Apakah semua project Laravel butuh Supervisor?

Tidak. Supervisor diperlukan jika project memakai queue worker di production.

Kenapa job masuk queue tetapi tidak jalan?

Biasanya worker belum berjalan, QUEUE_CONNECTION salah, tabel queue belum dibuat, atau Supervisor gagal start.

Berapa jumlah worker yang ideal?

Mulai dari 1 atau 2. Tambah jika antrean sering menumpuk dan server masih punya resource cukup.

Apakah perlu restart Supervisor setiap deploy?

Biasanya cukup jalankan php artisan queue:restart. Supervisor akan menjaga worker tetap hidup dan menjalankan proses baru setelah worker lama berhenti.