Laravel Scheduler Tidak Jalan di Ubuntu? Ini Cara Mengeceknya

Laravel Scheduler digunakan untuk menjalankan task secara otomatis berdasarkan jadwal tertentu. Misalnya menjalankan command setiap menit, membersihkan data setiap hari, mengirim laporan mingguan, atau menjalankan proses tertentu pada jam yang sudah ditentukan.

Di development, Scheduler biasanya terasa mudah digunakan. Namun setelah aplikasi Laravel dipindahkan ke Ubuntu VPS, sering muncul masalah seperti:

  • Laravel Scheduler tidak berjalan otomatis.
  • schedule:run bisa dijalankan manual, tetapi tidak berjalan melalui Cron.
  • Task tidak pernah dieksekusi meskipun sudah dibuat.
  • Scheduler berjalan pada waktu yang salah.
  • Command berjalan manual tetapi gagal ketika dijalankan Cron.
  • Task hanya berjalan sekali lalu berhenti.
  • withoutOverlapping() membuat task tidak berjalan lagi.
  • Scheduler tidak menjalankan task setelah deployment.

Masalah seperti ini biasanya bukan karena Laravel Scheduler rusak. Penyebabnya sering berada di Cron, path project, PHP CLI, timezone, permission, environment, konfigurasi cache, atau cara task didefinisikan.

Artikel ini membahas cara mengecek Laravel Scheduler di Ubuntu secara bertahap sampai menemukan sumber masalahnya.

Intinya: Laravel Scheduler di server membutuhkan pemicu eksternal. Pada setup Ubuntu dengan Cron, server menjalankan php artisan schedule:run setiap menit, kemudian Laravel menentukan task mana yang memang sudah waktunya dijalankan.


Bagaimana Laravel Scheduler Bekerja di Ubuntu?

Sebelum melakukan troubleshooting, penting memahami alurnya.

Laravel Scheduler bukan daemon yang otomatis berjalan sendiri hanya karena Anda membuat:

Schedule::command('example')->daily();

Pada server tradisional, Cron bertugas memanggil Laravel Scheduler setiap menit:

Ubuntu Cron
    ↓
php artisan schedule:run
    ↓
Laravel membaca jadwal
    ↓
Task yang sudah waktunya dijalankan
    ↓
Command / Job / Closure

Laravel merekomendasikan satu Cron entry yang menjalankan schedule:run setiap menit. Laravel kemudian mengevaluasi semua scheduled task dan menentukan mana yang harus dijalankan.

Jadi ketika Scheduler tidak berjalan, kita perlu memeriksa setiap bagian dari alur tersebut.


Penyebab Laravel Scheduler Tidak Berjalan

Beberapa penyebab yang paling umum adalah:

  1. Cron belum dibuat.
  2. Cron menggunakan path project yang salah.
  3. PHP CLI tidak ditemukan oleh Cron.
  4. php artisan schedule:run gagal dijalankan.
  5. Schedule belum didefinisikan dengan benar.
  6. Task memang ada tetapi belum waktunya dijalankan.
  7. Timezone server berbeda dengan timezone aplikasi.
  8. Permission user Cron tidak sesuai.
  9. Environment yang digunakan Cron berbeda dengan terminal.
  10. Configuration cache masih menggunakan konfigurasi lama.
  11. Task menggunakan withoutOverlapping() dan lock masih aktif.
  12. Aplikasi sedang maintenance mode.
  13. Task dijalankan melalui queue tetapi Queue Worker tidak aktif.
  14. Task terlalu lama dan menghambat task berikutnya.
  15. Deployment belum menangani scheduler yang sedang berjalan.

Mari kita periksa satu per satu.


1. Pastikan Scheduler Laravel Memang Sudah Didefinisikan

Pada Laravel versi modern, scheduled task umumnya dapat didefinisikan di:

routes/console.php

Contoh:

<?php

use Illuminate\Support\Facades\Schedule;

Schedule::command('inspire')->hourly();

Contoh lainnya:

Schedule::command('reports:generate')
    ->dailyAt('01:00');

Atau menjalankan Job:

Schedule::job(new ProcessDailyReport)
    ->dailyAt('02:00');

Laravel mendukung berbagai jenis scheduled task, termasuk Artisan command, queued job, shell command, dan closure.

Jika schedule belum didefinisikan, Cron bisa saja berjalan dengan normal tetapi tidak ada task yang harus dieksekusi.


2. Gunakan schedule:list untuk Melihat Schedule

Salah satu command paling berguna ketika melakukan troubleshooting adalah:

php artisan schedule:list

Command ini membantu melihat daftar scheduled task yang dikenali Laravel beserta jadwal eksekusinya.

Misalnya:

0 0 * * *  php artisan reports:generate
0 * * * *  php artisan emails:send
*/5 * * * * php artisan cache:clear

Jika task yang Anda harapkan tidak muncul sama sekali, jangan langsung mengecek Cron.

Masalah kemungkinan berada pada definisi Scheduler atau aplikasi belum memuat schedule tersebut.

Jika schedule tidak muncul

Periksa:

routes/console.php

Pastikan statement schedule benar dan tidak ada syntax error.

Kemudian jalankan:

php artisan schedule:list

Jika command tersebut sendiri menghasilkan error, selesaikan error Laravel terlebih dahulu.


3. Tes schedule:run Secara Manual

Ini adalah langkah paling penting.

Masuk ke direktori aplikasi Laravel:

cd /var/www/example.com

Kemudian jalankan:

php artisan schedule:run

Jika ada task yang memang waktunya sudah tiba, Laravel akan menjalankannya.

Perintah schedule:run hanya mengevaluasi task yang memang due pada saat command dijalankan. Jadi jika Anda memiliki:

Schedule::command('reports:generate')->dailyAt('02:00');

tetapi Anda menjalankan:

php artisan schedule:run

pada pukul 14:00, task tersebut memang tidak akan dijalankan.

Laravel menjelaskan bahwa schedule:run mengevaluasi semua scheduled task berdasarkan waktu server saat command tersebut dipanggil.


4. Buat Schedule Test Setiap Menit

Jika Anda ingin memastikan Scheduler bekerja, buat sementara task yang berjalan setiap menit.

Contoh:

Schedule::call(function () {
    \Log::info('Laravel Scheduler berhasil dijalankan');
})->everyMinute();

Kemudian jalankan:

php artisan schedule:run

Jika konfigurasi Scheduler benar, Anda dapat memeriksa:

tail -f storage/logs/laravel.log

Cari:

Laravel Scheduler berhasil dijalankan

Ini lebih baik daripada langsung menguji task kompleks seperti generate laporan atau sinkronisasi API.

Mengapa?

Karena troubleshooting sebaiknya dimulai dari:

Scheduler bekerja?
        ↓
Cron bekerja?
        ↓
Task terdeteksi?
        ↓
Task berhasil?

Bukan langsung menguji semua komponen sekaligus.


5. Pastikan Cron Ubuntu Sudah Dibuat

Setelah schedule:run berhasil secara manual, langkah berikutnya adalah memeriksa Cron.

Buka Crontab user yang menjalankan aplikasi:

crontab -e

Tambahkan:

* * * * * cd /var/www/example.com && php artisan schedule:run >> /dev/null 2>&1

Laravel merekomendasikan satu Cron entry seperti ini untuk menjalankan Scheduler setiap menit.

Ganti:

/var/www/example.com

dengan lokasi project Laravel Anda.

Misalnya:

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

6. Pastikan Cron Benar-Benar Tersimpan

Setelah menjalankan:

crontab -e

periksa kembali:

crontab -l

Pastikan Anda melihat:

* * * * * cd /var/www/example.com && php artisan schedule:run >> /dev/null 2>&1

Jika entry tidak muncul, berarti Cron belum tersimpan pada user tersebut.

Ini merupakan kesalahan sederhana tetapi cukup sering terjadi.


7. Jangan Menggunakan Path yang Salah

Misalnya project Laravel sebenarnya berada di:

/var/www/myapp

tetapi Cron menggunakan:

* * * * * cd /var/www/example.com && php artisan schedule:run

Cron akan gagal.

Periksa lokasi project:

pwd

Ketika berada di root project Laravel, hasilnya misalnya:

/var/www/myapp

Pastikan path tersebut sama dengan yang digunakan di Cron.

Anda juga dapat memeriksa keberadaan Artisan:

ls -lah /var/www/myapp/artisan

Jika file artisan tidak ditemukan, path project salah.


8. Jangan Mengandalkan php Tanpa Memastikan PATH

Ini salah satu penyebab Scheduler sering gagal di Cron.

Di terminal SSH, perintah ini mungkin berhasil:

php artisan schedule:run

Tetapi Cron memiliki environment yang lebih minimal dibanding shell interaktif.

Karena itu, cari lokasi PHP:

which php

Contohnya:

/usr/bin/php

Kemudian gunakan absolute path di Cron:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run >> /dev/null 2>&1

Jika Anda menggunakan versi PHP tertentu, path-nya bisa berbeda.

Periksa:

php -v

dan:

which php

9. Bandingkan PHP Terminal dengan PHP Cron

Masalah yang lebih sulit terjadi ketika server mempunyai beberapa versi PHP.

Misalnya terminal menggunakan:

PHP 8.3

tetapi Cron menjalankan:

PHP 8.1

Akibatnya:

Terminal
    ↓
PHP 8.3
    ↓
Laravel berhasil

Cron
    ↓
PHP 8.1
    ↓
Error

Periksa:

php -v

Kemudian:

which php

Gunakan hasil which php tersebut di Cron jika diperlukan.

Contoh:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run >> /var/log/laravel-scheduler.log 2>&1

Untuk troubleshooting, jangan langsung membuang output Cron ke /dev/null.

Lebih baik simpan output sementara ke file agar error dapat diperiksa.


10. Simpan Output Cron ke Log

Daripada:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run >> /dev/null 2>&1

sementara gunakan:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run >> /var/log/laravel-scheduler.log 2>&1

Kemudian periksa:

tail -f /var/log/laravel-scheduler.log

Jika ada error seperti:

Could not open input file: artisan

kemungkinan path project salah.

Jika:

php: command not found

kemungkinan PATH atau lokasi PHP bermasalah.

Jika:

Permission denied

periksa user dan permission.

Setelah masalah ditemukan, Anda dapat mengembalikan output ke:

>> /dev/null 2>&1

atau mengarahkan ke log yang memang Anda kelola.


11. Pastikan Service Cron Ubuntu Berjalan

Periksa status Cron:

sudo systemctl status cron

Pada Ubuntu, service biasanya bernama:

cron

Jika statusnya tidak aktif, jalankan:

sudo systemctl start cron

Agar otomatis berjalan setelah server restart:

sudo systemctl enable cron

Anda juga dapat memastikan Cron aktif dengan:

systemctl is-active cron

Jika hasilnya:

active

service Cron sedang berjalan.


12. Periksa Log Cron

Jika Cron terlihat aktif tetapi Scheduler tetap tidak berjalan, periksa log sistem.

Pada Ubuntu yang menggunakan syslog, Anda dapat mencoba:

sudo grep CRON /var/log/syslog

Atau:

sudo tail -f /var/log/syslog

Cari entry yang berhubungan dengan:

CRON

Jika Cron benar-benar memanggil command Laravel, biasanya akan ada jejak eksekusinya di log sistem.

Ini membantu membedakan dua masalah:

Cron tidak menjalankan command

dengan:

Cron menjalankan command tetapi Laravel gagal

Keduanya membutuhkan solusi yang berbeda.


13. Periksa User yang Menjalankan Cron

Cron tidak selalu berjalan sebagai user yang sama dengan user SSH Anda.

Misalnya Anda login sebagai:

root

tetapi aplikasi dijalankan oleh:

www-data

atau:

deploy

Cron yang Anda buat dengan:

crontab -e

berlaku untuk user yang sedang digunakan.

Periksa:

whoami

Kemudian:

crontab -l

Jika Anda memang ingin Cron berjalan sebagai user tertentu, Anda perlu memastikan konfigurasi tersebut dibuat pada user yang tepat.

Ini penting karena user berbeda dapat mempunyai:

  • PATH berbeda,
  • PHP berbeda,
  • permission berbeda,
  • environment berbeda,
  • akses file berbeda.

14. Periksa Permission Project

Cron dapat gagal karena user yang menjalankan Scheduler tidak mempunyai permission terhadap project Laravel.

Periksa:

ls -lah /var/www/myapp

Kemudian periksa:

ls -lah /var/www/myapp/storage

dan:

ls -lah /var/www/myapp/bootstrap/cache

Laravel membutuhkan akses tulis pada direktori yang diperlukan aplikasi, terutama storage dan bootstrap/cache.

Jika command berjalan sebagai user berbeda, pastikan user tersebut mempunyai permission yang sesuai.

Jangan langsung memberikan:

chmod -R 777

sebagai solusi.

Permission 777 bukan solusi umum untuk masalah Laravel Scheduler dan dapat membuka risiko keamanan yang tidak perlu.


15. Periksa Timezone Ubuntu

Salah satu penyebab paling membingungkan adalah:

“Scheduler jalan, tetapi bukan pada jam yang saya tentukan.”

Periksa timezone server:

timedatectl

Contoh:

Time zone: Asia/Jakarta (WIB, +0700)

Anda juga dapat melihat waktu server:

date

Pastikan waktu server sesuai dengan waktu yang Anda harapkan.

Misalnya Anda mempunyai:

Schedule::command('reports:generate')
    ->dailyAt('02:00');

Jika server menggunakan UTC tetapi Anda menganggap waktunya WIB, task dapat berjalan pada waktu yang berbeda dari ekspektasi.


16. Bedakan Timezone Server dan Timezone Laravel

Laravel dapat menggunakan timezone tertentu untuk Scheduler.

Contoh:

Schedule::command('reports:generate')
    ->dailyAt('02:00')
    ->timezone('Asia/Jakarta');

Laravel juga menyediakan konfigurasi schedule_timezone untuk menetapkan timezone default bagi scheduled tasks.

Contohnya di konfigurasi aplikasi:

'schedule_timezone' => 'Asia/Jakarta',

Jika Anda memang membutuhkan jadwal berdasarkan timezone tertentu, pastikan timezone tersebut sengaja dikonfigurasi.

Untuk aplikasi yang seluruh server dan user-nya menggunakan timezone yang sama, konfigurasi sederhana biasanya lebih mudah dipelihara.


17. Pastikan Task Memang Sudah Due

Misalnya Anda memiliki:

Schedule::command('reports:generate')
    ->dailyAt('02:00');

Kemudian Anda menjalankan:

php artisan schedule:run

pada pukul:

14:00

Anda mungkin mengira Scheduler rusak karena command tidak berjalan.

Padahal Laravel hanya menjalankan task ketika waktunya sudah sesuai.

Karena itu, gunakan:

php artisan schedule:list

untuk melihat jadwal task dan waktu eksekusi berikutnya.


18. Tes dengan everyMinute()

Jika Anda masih ragu apakah Scheduler bekerja, ubah sementara task menjadi:

Schedule::command('reports:generate')
    ->everyMinute();

Atau gunakan command sederhana:

Schedule::command('inspire')
    ->everyMinute();

Kemudian pastikan Cron menjalankan:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run

Tunggu sekitar satu atau dua menit.

Jika task berjalan, berarti mekanisme Scheduler sudah benar dan masalah kemungkinan berada pada:

  • frequency,
  • timezone,
  • condition,
  • atau constraint pada task.

Setelah selesai testing, kembalikan jadwal sebenarnya.


19. Periksa withoutOverlapping()

Laravel menyediakan:

->withoutOverlapping()

untuk mencegah task yang sama berjalan bersamaan ketika proses sebelumnya belum selesai. Lock tersebut menggunakan cache aplikasi.

Contoh:

Schedule::command('reports:generate')
    ->everyMinute()
    ->withoutOverlapping();

Jika proses pertama membutuhkan waktu lama, eksekusi berikutnya tidak akan dimulai selama lock masih dianggap aktif.

Ini bisa terlihat seperti:

Laravel Scheduler tidak jalan.

Padahal sebenarnya:

Scheduler berjalan, tetapi task dicegah karena masih memiliki lock.


20. Bersihkan Lock Scheduler

Jika task menggunakan:

->withoutOverlapping()

dan Anda yakin tidak ada proses yang masih berjalan tetapi task tetap tidak dieksekusi, periksa kemungkinan lock yang tertinggal.

Laravel menyediakan:

php artisan schedule:clear-cache

untuk membersihkan cache lock Scheduler. Dokumentasi Laravel menyebut command ini terutama berguna ketika task menjadi stuck karena masalah server yang tidak terduga.

Jangan menjadikan schedule:clear-cache sebagai solusi pertama setiap kali Scheduler bermasalah.

Gunakan setelah memastikan memang ada masalah lock.


21. Periksa Configuration Cache

Masalah lain dapat muncul setelah Anda mengubah:

.env

atau konfigurasi aplikasi.

Jika production menggunakan configuration cache:

php artisan config:cache

Laravel akan menyimpan konfigurasi ke dalam cache sehingga .env tidak dibaca seperti pada kondisi development biasa ketika aplikasi menjalankan request atau Artisan command. Laravel menyediakan config:clear untuk membersihkan cached configuration.

Jika Anda baru saja mengubah konfigurasi yang berkaitan dengan:

  • timezone,
  • database,
  • Redis,
  • queue,
  • environment,

periksa konfigurasi yang benar-benar sedang digunakan aplikasi.

Untuk membersihkan cache konfigurasi:

php artisan config:clear

Kemudian, jika deployment production Anda memang menggunakan configuration cache:

php artisan config:cache

Jangan menjalankan config:cache secara sembarangan pada development karena konfigurasi sering berubah selama proses pengembangan.


22. Periksa APP_ENV

Task tertentu dapat dibatasi berdasarkan environment.

Contoh:

Schedule::command('emails:send')
    ->daily()
    ->environments(['production']);

Laravel menyediakan environments() untuk membatasi scheduled task berdasarkan nilai APP_ENV.

Jika:

APP_ENV=local

sementara task hanya boleh berjalan pada:

production

task tidak akan dieksekusi.

Periksa:

php artisan about

dan konfigurasi environment aplikasi Anda.


23. Periksa Maintenance Mode

Scheduled tasks Laravel secara default tidak dijalankan ketika aplikasi berada dalam maintenance mode.

Jika aplikasi sedang:

php artisan down

Scheduler dapat tidak menjalankan task seperti biasanya. Laravel menyediakan evenInMaintenanceMode() jika task tertentu memang harus tetap berjalan ketika aplikasi dalam maintenance mode.

Jika aplikasi sedang maintenance, periksa:

php artisan up

untuk mengembalikan aplikasi ke kondisi normal.

Gunakan evenInMaintenanceMode() hanya untuk task yang memang diperlukan selama maintenance.


24. Scheduler Berhasil, Tetapi Queue Tidak Berjalan

Ini kasus yang sangat penting.

Misalnya Scheduler Anda:

Schedule::job(new SendDailyReport)
    ->dailyAt('08:00');

Scheduler mungkin sudah bekerja dengan benar.

Tetapi Job tersebut masuk ke Queue:

Scheduler
    ↓
Dispatch Job
    ↓
Redis
    ↓
Queue Worker
    ↓
SendDailyReport

Jika Queue Worker tidak berjalan, Anda mungkin menyimpulkan:

Laravel Scheduler tidak berjalan.

Padahal sebenarnya:

Scheduler → berhasil
Queue Worker → bermasalah

Periksa:

php artisan queue:work

Jika menggunakan Redis:

php artisan queue:work redis

Untuk production, pastikan Worker dikelola dengan Supervisor atau process manager lainnya.

Ini sangat relevan jika aplikasi Anda menggunakan Laravel + Redis + Queue.


25. Scheduled Command Gagal, Bukan Scheduler-nya

Misalnya:

Schedule::command('reports:generate')
    ->daily();

Scheduler dapat berhasil memanggil:

php artisan reports:generate

tetapi command tersebut mengalami exception.

Jadi ada perbedaan antara:

Scheduler tidak menjalankan task

dan:

Scheduler menjalankan task tetapi task gagal

Tes command secara manual:

php artisan reports:generate

Jika command tersebut gagal secara manual, perbaiki command-nya terlebih dahulu.

Jangan fokus pada Cron jika Artisan command sendiri memang bermasalah.


26. Periksa Log Laravel

Ketika scheduled command gagal, periksa:

tail -f storage/logs/laravel.log

Cari error seperti:

SQLSTATE
Connection refused
RedisException
Permission denied
Class not found
Call to undefined method
Allowed memory size exhausted

Jika Cron menjalankan command tetapi task gagal, error biasanya lebih mudah dilacak dari log aplikasi atau output command.

Untuk debugging, jangan sembunyikan semua output dengan:

>> /dev/null 2>&1

sampai Anda yakin Scheduler sudah normal.


27. Simpan Output Scheduled Task

Laravel juga menyediakan mekanisme untuk menyimpan output task.

Contoh:

Schedule::command('reports:generate')
    ->daily()
    ->sendOutputTo(storage_path('logs/reports-scheduler.log'));

Atau:

Schedule::command('reports:generate')
    ->daily()
    ->appendOutputTo(storage_path('logs/reports-scheduler.log'));

Laravel mendukung sendOutputTo() dan appendOutputTo() untuk menyimpan output scheduled command ke file.

Ini berguna ketika command menghasilkan output yang ingin Anda audit.


28. Hati-Hati dengan Task yang Lama

Misalnya Anda mempunyai:

Schedule::command('reports:generate')
    ->hourly();

Tetapi command tersebut membutuhkan waktu:

70 menit

Task berikutnya bisa mengalami masalah karena proses sebelumnya belum selesai.

Secara default, scheduled tasks yang waktunya sama dapat dieksekusi secara berurutan. Laravel menyediakan runInBackground() untuk command dan shell command tertentu jika Anda ingin task berjalan di background.

Contoh:

Schedule::command('reports:generate')
    ->hourly()
    ->runInBackground();

Namun jangan menggunakan runInBackground() hanya sebagai solusi jika command sebenarnya terlalu lambat.

Lebih baik ukur dan optimalkan proses tersebut terlebih dahulu.


29. Gunakan withoutOverlapping() untuk Task yang Berat

Jika task membutuhkan waktu cukup lama dan tidak boleh berjalan bersamaan, gunakan:

Schedule::command('reports:generate')
    ->hourly()
    ->withoutOverlapping();

Dengan demikian, Laravel tidak akan menjalankan instance berikutnya jika instance sebelumnya masih memiliki lock.

Ini sangat berguna untuk:

  • generate laporan,
  • import data,
  • sinkronisasi API,
  • cleanup database,
  • proses batch.

30. Jika Menggunakan Banyak Server

Pada aplikasi dengan beberapa server, Scheduler dapat dijalankan pada lebih dari satu mesin.

Misalnya:

Server 1 → Scheduler
Server 2 → Scheduler
Server 3 → Scheduler

Tanpa mekanisme pencegahan yang tepat, task tertentu bisa dijalankan lebih dari sekali.

Laravel menyediakan:

->onOneServer()

untuk membatasi task agar hanya dijalankan oleh satu server. Fitur ini membutuhkan cache yang mendukung atomic lock dan server-server tersebut harus menggunakan cache terpusat yang sama.

Contoh:

Schedule::command('reports:generate')
    ->daily()
    ->onOneServer();

Ini sangat relevan pada deployment horizontal atau load-balanced.


31. Cara Debugging Paling Cepat

Jika Anda sedang SSH ke Ubuntu dan Scheduler tidak berjalan, gunakan urutan berikut.

Langkah 1 — Lihat schedule

php artisan schedule:list

Jika task tidak muncul, periksa definisi Scheduler.

Langkah 2 — Jalankan scheduler manual

php artisan schedule:run

Jika error, perbaiki error tersebut.

Langkah 3 — Tes task sederhana

Gunakan:

Schedule::call(function () {
    \Log::info('Scheduler OK');
})->everyMinute();

Langkah 4 — Periksa Cron

crontab -l

Pastikan terdapat:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run

Langkah 5 — Periksa service Cron

sudo systemctl status cron

Langkah 6 — Periksa log Cron

sudo grep CRON /var/log/syslog

Langkah 7 — Periksa log Laravel

tail -f storage/logs/laravel.log

Langkah 8 — Jika task menggunakan Queue

Periksa worker:

php artisan queue:work redis

Dengan urutan tersebut, Anda dapat mempersempit masalah tanpa mengubah banyak konfigurasi secara acak.


Contoh Cron Laravel yang Direkomendasikan

Untuk project Laravel di:

/var/www/myapp

Anda dapat menggunakan:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run >> /dev/null 2>&1

Untuk debugging, ubah sementara menjadi:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run >> /var/log/laravel-scheduler.log 2>&1

Kemudian:

tail -f /var/log/laravel-scheduler.log

Setelah Scheduler dipastikan normal, Anda dapat mengembalikan output ke /dev/null atau menggunakan mekanisme logging yang sesuai.


Contoh Scheduler Laravel untuk Testing

Untuk pengujian sederhana:

<?php

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schedule;

Schedule::call(function () {
    Log::info('Laravel Scheduler berjalan: ' . now());
})->everyMinute();

Kemudian:

php artisan schedule:list

Pastikan task muncul.

Selanjutnya:

php artisan schedule:run

Lalu:

tail -f storage/logs/laravel.log

Jika Anda melihat:

Laravel Scheduler berjalan

berarti Laravel Scheduler dapat menjalankan task.

Berikutnya tinggal memastikan Cron yang memanggil schedule:run bekerja setiap menit.


Bagaimana Mengetahui Cron Benar-Benar Memanggil Laravel?

Cara paling mudah adalah membuat log sementara.

Cron:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run >> /var/log/laravel-scheduler.log 2>&1

Kemudian:

tail -f /var/log/laravel-scheduler.log

Anda juga dapat memeriksa log sistem:

sudo grep CRON /var/log/syslog

Jika Cron muncul di log sistem tetapi Laravel tidak menghasilkan output yang diharapkan, fokuskan pemeriksaan pada:

  • path project,
  • PHP CLI,
  • Artisan,
  • permission,
  • environment,
  • konfigurasi Laravel,
  • dan scheduled task.

Checklist Laravel Scheduler di Ubuntu

Gunakan checklist berikut ketika Scheduler tidak berjalan:

[ ] Schedule sudah didefinisikan
[ ] Task muncul di php artisan schedule:list
[ ] php artisan schedule:run berhasil dijalankan manual
[ ] Task memang sudah due
[ ] crontab sudah dibuat
[ ] crontab -l menampilkan konfigurasi yang benar
[ ] Path project Laravel benar
[ ] File artisan ditemukan
[ ] Path PHP CLI benar
[ ] Versi PHP CLI sesuai
[ ] Service cron berstatus active
[ ] User Cron memiliki permission yang sesuai
[ ] storage dapat ditulis
[ ] bootstrap/cache dapat diakses
[ ] Timezone server benar
[ ] Timezone Laravel benar
[ ] APP_ENV sesuai
[ ] Configuration cache tidak menggunakan konfigurasi lama
[ ] Tidak ada lock dari withoutOverlapping
[ ] Tidak sedang maintenance mode
[ ] Scheduled command tidak mengalami error
[ ] Queue Worker aktif jika Scheduler dispatch Job
[ ] Log Laravel tidak menunjukkan error

Laravel Scheduler Tidak Jalan? Gunakan Alur Ini

Jika ingin mengingat satu pola troubleshooting saja, gunakan:

1. schedule:list
        ↓
2. schedule:run
        ↓
3. Tes task sederhana
        ↓
4. crontab -l
        ↓
5. systemctl status cron
        ↓
6. Periksa path PHP
        ↓
7. Periksa timezone
        ↓
8. Periksa permission
        ↓
9. Periksa Laravel log
        ↓
10. Periksa Queue Worker

Dengan pendekatan tersebut, Anda bisa menentukan apakah masalahnya berada di:

Laravel
Cron
PHP CLI
Permission
Timezone
Cache/Lock
Queue

Kesimpulan

Ketika Laravel Scheduler tidak berjalan di Ubuntu, jangan langsung membuat banyak Cron entry.

Laravel dirancang agar Anda cukup memiliki satu Cron entry yang menjalankan:

php artisan schedule:run

setiap menit. Setelah itu Laravel yang menentukan task mana yang harus dijalankan berdasarkan schedule yang Anda definisikan.

Mulailah troubleshooting dari:

php artisan schedule:list

kemudian:

php artisan schedule:run

Jika keduanya bekerja, periksa Cron:

crontab -l

dan pastikan terdapat:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run

Jika Cron juga benar, lanjutkan ke pemeriksaan:

  • PHP CLI,
  • timezone,
  • permission,
  • configuration cache,
  • withoutOverlapping(),
  • maintenance mode,
  • scheduled command,
  • dan Queue Worker.

Hal yang juga penting adalah membedakan Scheduler tidak berjalan dengan task yang dijalankan Scheduler mengalami error.

Pada aplikasi yang menggunakan Laravel + Redis + Queue, alurnya bisa menjadi:

Cron
 ↓
Laravel Scheduler
 ↓
Dispatch Job
 ↓
Redis
 ↓
Queue Worker
 ↓
Job

Jika Job tidak diproses, masalah belum tentu berada pada Scheduler.

Dengan memahami alur tersebut, proses troubleshooting menjadi jauh lebih cepat dan tidak perlu mencoba berbagai konfigurasi secara acak.


FAQ

Apakah Laravel Scheduler membutuhkan Cron?

Pada server tradisional seperti Ubuntu VPS, Laravel Scheduler biasanya dipicu oleh satu Cron entry yang menjalankan php artisan schedule:run setiap menit. Laravel kemudian mengevaluasi scheduled tasks yang sudah waktunya dijalankan.

Kenapa php artisan schedule:run tidak menjalankan task?

Pastikan task memang sudah due pada waktu tersebut. Gunakan:

php artisan schedule:list

Jika task tidak muncul, periksa definisi Scheduler.

Kenapa Scheduler berjalan manual tetapi tidak melalui Cron?

Penyebab yang umum adalah Cron menggunakan user, PATH, PHP binary, environment, atau working directory yang berbeda dari terminal SSH.

Coba gunakan absolute path:

* * * * * cd /var/www/myapp && /usr/bin/php artisan schedule:run

Bagaimana cara melihat daftar Laravel Scheduler?

Gunakan:

php artisan schedule:list

Command tersebut membantu melihat scheduled task dan jadwal eksekusinya.

Bagaimana cara menjalankan Laravel Scheduler secara manual?

Gunakan:

php artisan schedule:run

Untuk development, Anda juga dapat menggunakan:

php artisan schedule:work

schedule:work menjalankan scheduler di foreground dan terus memanggil scheduler secara berkala sampai dihentikan.

Kenapa Laravel Scheduler berjalan pada jam yang salah?

Periksa timezone Ubuntu:

timedatectl

Kemudian periksa timezone Laravel dan konfigurasi schedule. Laravel mendukung timezone khusus per task maupun schedule_timezone sebagai timezone default Scheduler.

Apa fungsi withoutOverlapping()?

withoutOverlapping() mencegah scheduled task dijalankan kembali ketika instance sebelumnya masih dianggap berjalan. Laravel menggunakan cache lock untuk mekanisme tersebut. Jika lock tertinggal karena masalah server, Anda dapat menggunakan:

php artisan schedule:clear-cache

untuk membersihkan lock Scheduler.

Apakah Laravel Scheduler membutuhkan Supervisor?

Tidak untuk Scheduler itu sendiri jika Anda menggunakan Cron. Cron memanggil schedule:run setiap menit.

Supervisor lebih umum digunakan untuk Laravel Queue Worker yang merupakan proses jangka panjang.

Kenapa Scheduler berhasil tetapi Job tidak diproses?

Jika Scheduler melakukan:

Schedule::job(new SendReport)->daily();

Scheduler mungkin berhasil melakukan dispatch Job, tetapi Queue Worker bisa saja tidak aktif.

Periksa:

php artisan queue:work

atau process manager seperti Supervisor.