Cara Menjalankan Scheduler Laravel di Production

Scheduler Laravel di production dijalankan dengan satu cron entry yang memanggil php artisan schedule:run setiap menit. Jawaban cepatnya: definisikan jadwal di aplikasi Laravel, tambahkan cron di server, pastikan path project benar, pakai user yang punya permission, lalu cek log jika task tidak jalan.

Scheduler sering membingungkan pemula karena task berjalan otomatis di belakang layar. Di lokal kamu bisa menjalankan perintah manual, tetapi di server production Laravel butuh cron dari sistem operasi agar jadwal dievaluasi terus-menerus.

Apa Itu Scheduler Laravel?

Scheduler adalah fitur Laravel untuk menjalankan pekerjaan terjadwal, misalnya:

  • mengirim email laporan setiap pagi
  • membersihkan token kadaluarsa setiap malam
  • membuat backup database harian
  • mengecek pembayaran yang masih pending
  • memproses notifikasi yang harus dikirim berkala

Tanpa scheduler, kamu biasanya harus membuat banyak cron entry manual. Dengan scheduler, jadwal ditulis di project Laravel, lalu server cukup menjalankan satu perintah setiap menit.

Alurnya seperti ini:

Cron server
  -> php artisan schedule:run
  -> Laravel mengecek jadwal
  -> task yang sudah waktunya dijalankan

Tempat Menulis Jadwal

Pada Laravel versi baru, jadwal biasanya ditulis di routes/console.php:

<?php

use Illuminate\Support\Facades\Schedule;

Schedule::command('invoices:send-reminder')
    ->dailyAt('08:00');

Schedule::command('orders:sync-payment')
    ->everyFiveMinutes();

Pada project Laravel lama, kamu mungkin masih menemukan jadwal di app/Console/Kernel.php:

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    protected function schedule(Schedule $schedule): void
    {
        $schedule->command('invoices:send-reminder')->dailyAt('08:00');
        $schedule->command('orders:sync-payment')->everyFiveMinutes();
    }
}

Pilih lokasi yang sesuai dengan struktur project kamu. Jangan pindahkan semua file hanya karena contoh tutorial berbeda versi.

Contoh Command yang Dijadwalkan

Buat command baru:

php artisan make:command BersihkanLogLama

Contoh isi command:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

class BersihkanLogLama extends Command
{
    protected $signature = 'logs:clean-old';

    protected $description = 'Menghapus file log aplikasi yang sudah tidak diperlukan';

    public function handle(): int
    {
        foreach (File::files(storage_path('logs')) as $file) {
            if ($file->getMTime() < now()->subDays(14)->timestamp) {
                File::delete($file->getPathname());
            }
        }

        $this->info('Log lama selesai dibersihkan.');

        return self::SUCCESS;
    }
}

Jalankan manual dulu:

php artisan logs:clean-old

Kalau command manual saja error, scheduler juga akan error. Selesaikan dulu error command sebelum memasangnya ke cron.

Tambahkan Cron di Server

Masuk ke server, lalu buka crontab untuk user yang menjalankan aplikasi:

crontab -e

Tambahkan baris ini:

* * * * * cd /var/www/toko-laravel && php artisan schedule:run >> /dev/null 2>&1

Sesuaikan /var/www/toko-laravel dengan folder project kamu. Bagian cd penting karena Laravel membaca file, .env, dan path relatif dari folder project.

Jika server punya beberapa versi PHP, gunakan path PHP yang eksplisit:

* * * * * cd /var/www/toko-laravel && /usr/bin/php8.3 artisan schedule:run >> /dev/null 2>&1

Cek lokasi PHP:

which php
php -v

Cara Mengecek Scheduler Berjalan

Mulai dari perintah ini:

php artisan schedule:list
php artisan schedule:run

schedule:list membantu melihat task yang terdaftar. schedule:run menjalankan evaluasi jadwal saat itu juga.

Untuk memastikan cron benar-benar memanggil scheduler, sementara arahkan output ke file log:

* * * * * cd /var/www/toko-laravel && php artisan schedule:run >> storage/logs/scheduler.log 2>&1

Lalu cek:

tail -f storage/logs/scheduler.log
tail -f storage/logs/laravel.log

Setelah stabil, kamu bisa mengembalikan output ke /dev/null atau tetap menyimpan log jika project membutuhkannya.

Scheduler vs Queue Worker

Scheduler dan queue worker sering tertukar.

FiturTugas
Schedulermenentukan kapan command dijalankan
Queue workermemproses job yang masuk antrean
Supervisormenjaga queue worker tetap hidup

Contoh: scheduler menjalankan command reports:send setiap pagi. Command itu bisa langsung mengirim email, atau lebih baik men-dispatch job ke queue. Queue worker lalu memproses job tersebut di belakang.

Jika task yang dijadwalkan berat, jangan semua dikerjakan langsung di scheduler. Dispatch job ke queue agar scheduler tetap ringan.

<?php

use App\Jobs\KirimLaporanHarian;
use Illuminate\Support\Facades\Schedule;

Schedule::call(function () {
    KirimLaporanHarian::dispatch();
})->dailyAt('07:00');

Kesalahan yang Sering Terjadi

Menjalankan schedule:work di Production

schedule:work berguna untuk development karena prosesnya berjalan terus di terminal. Untuk production VPS biasa, gunakan cron yang memanggil schedule:run setiap menit.

Path Project Salah

Cron ini akan gagal jika foldernya salah:

* * * * * cd /var/www/salah-folder && php artisan schedule:run

Pastikan path sama dengan lokasi file artisan.

PHP CLI Berbeda dari PHP-FPM

Nginx bisa memakai PHP 8.3, tetapi terminal memakai PHP 8.1. Ini bisa membuat scheduler error karena dependency tidak cocok.

php -v
sudo systemctl status php8.3-fpm

Samakan versi PHP CLI dengan versi production yang kamu pakai.

User Cron Tidak Punya Permission

Jika cron berjalan sebagai user berbeda, scheduler bisa gagal menulis log, cache, atau file di storage.

sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R ug+rw storage bootstrap/cache

Sesuaikan www-data dengan user server kamu.

Task Berat Dijalankan Setiap Menit

Jangan menjalankan query besar, export besar, atau panggilan API lambat setiap menit tanpa batasan. Gunakan queue, cache, lock, atau interval yang lebih aman.

Pencegahan

  1. Test command secara manual sebelum dijadwalkan.
  2. Jalankan php artisan schedule:list setelah deploy.
  3. Gunakan path project absolut di crontab.
  4. Pastikan PHP CLI dan PHP-FPM memakai versi yang sama.
  5. Simpan log sementara saat debugging scheduler.
  6. Dispatch job ke queue untuk pekerjaan berat.

Bacaan Terkait

Referensi Resmi

FAQ

Apakah scheduler butuh Supervisor?

Tidak untuk scheduler itu sendiri. Scheduler biasanya cukup memakai cron. Supervisor dipakai untuk menjaga queue worker tetap berjalan.

Kenapa scheduler tidak jalan padahal command bisa manual?

Biasanya karena cron memakai path project salah, user berbeda, environment berbeda, atau versi PHP CLI berbeda dari yang kamu pakai saat mengetes manual.

Apakah cron harus setiap menit?

Ya, pola umum Laravel adalah satu cron setiap menit. Laravel yang menentukan task mana yang benar-benar due pada menit itu.

Apakah boleh menulis banyak cron untuk banyak command?

Bisa, tetapi tidak perlu untuk fitur scheduler Laravel. Lebih rapi tulis jadwal di Laravel dan pakai satu cron server.

Bagaimana kalau server restart?

Cron akan tetap tersedia setelah server hidup lagi selama service cron aktif. Queue worker tetap butuh process monitor seperti Supervisor.