September 27, 2026

Cron di Linux Server.

Panduan praktis crontab: sintaks lima kolom, contoh jadwal, jebakan environment dan PATH, logging output, locking, serta perbandingan dengan systemd timer.

Cron adalah penjadwal tugas klasik di Unix/Linux. Daemon cron bangun setiap menit, membaca daftar jadwal, lalu menjalankan perintah yang waktunya cocok. Cron cocok untuk backup harian, membersihkan file lama, menjalankan php artisan schedule:run, atau memperbarui sertifikat.

Catatan ini melanjutkan contekan CRON Basics dengan fokus ke pemakaian di server Ubuntu: di mana jadwal disimpan, kenapa job “jalan di terminal tapi tidak di cron”, dan cara mencatat log-nya.


1. Sintaks Crontab

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ menit        (0–59)
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ jam          (0–23)
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ tanggal      (1–31)
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€ bulan        (1–12 atau jan–dec)
β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€ hari minggu  (0–7, 0 dan 7 = Minggu, atau sun–sat)
β”‚ β”‚ β”‚ β”‚ β”‚
* * * * *  perintah
SimbolArtiContoh
*Semua nilai* di kolom jam = setiap jam
,Daftar1,15 = tanggal 1 dan 15
-Rentang1-5 = Senin–Jumat
/Kelipatan*/10 di kolom menit = tiap 10 menit

Shortcut (didukung cron di Ubuntu/Debian):

ShortcutSetara
@rebootSekali saat cron start (setelah boot)
@hourly0 * * * *
@daily0 0 * * *
@weekly0 0 * * 0
@monthly0 0 1 * *
@yearly0 0 1 1 *

2. Contoh Jadwal

EkspresiKapan
*/5 * * * *Setiap 5 menit
0 * * * *Setiap jam, menit ke-0
30 2 * * *Setiap hari 02:30
0 8 * * 1-5Senin–Jumat 08:00
0 0 1 * *Tanggal 1 tiap bulan, tengah malam
15 3 * * 0Minggu 03:15
0 9-17 * * 1-5Tiap jam kerja, Senin–Jumat
0 0 1,15 * *Tanggal 1 dan 15

Peringatan: Jika kolom tanggal dan hari minggu sama-sama diisi (bukan *), cron memakai logika OR, bukan AND. 0 0 13 * 5 berjalan setiap tanggal 13 dan setiap hari Jumat, bukan hanya “Jumat tanggal 13”.

Cron tidak mendukung satuan detik. Untuk “setiap 30 detik”, pakai systemd timer atau dua baris dengan sleep 30.


3. Di Mana Jadwal Disimpan

LokasiMilikFormat
crontab -e (disimpan di /var/spool/cron/crontabs/<user>)Per user5 kolom + perintah
/etc/crontabSistem5 kolom + user + perintah
/etc/cron.d/*Paket/admin5 kolom + user + perintah
/etc/cron.hourly/, daily/, weekly/, monthly/SistemSkrip executable, dijalankan oleh run-parts

Perintah untuk crontab user:

crontab -e             # edit crontab user saat ini
crontab -l             # tampilkan
crontab -r             # HAPUS semua (tanpa konfirmasi!)
sudo crontab -u www-data -e   # edit crontab user lain

Tips: crontab -r bersebelahan dengan -e di keyboard dan langsung menghapus semuanya. Backup rutin: crontab -l > ~/crontab.bak.

Contoh file di /etc/cron.d/ (perhatikan kolom user):

# /etc/cron.d/laravel-scheduler
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

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

Aturan file di /etc/cron.d/ dan folder cron.daily dll. di Debian/Ubuntu: nama file hanya boleh berisi huruf, angka, -, dan _. File bernama backup.sh atau app.conf (ada titik) diam-diam diabaikan. File di /etc/cron.d/ juga harus dimiliki root dan tidak writable oleh group/other.


4. Jebakan Environment dan PATH

Penyebab nomor satu “script jalan di terminal, tapi tidak di cron”: cron menjalankan perintah dengan environment minimal.

Di terminalDi cron
PATH lengkap (termasuk /usr/local/bin, nvm, pyenv)Biasanya hanya /usr/bin:/bin
Shell bash dengan .bashrc/.profile/bin/sh (dash di Ubuntu), tanpa .bashrc
Direktori kerja = folder sekarangDirektori home user
Variabel .env terbaca dari shellTidak ada

Solusi:

1. Set PATH dan SHELL di atas crontab

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""

2. Pakai path absolut untuk semua binary dan file:

which php node python3   # cari path-nya dulu
0 2 * * * /usr/bin/php /var/www/app/artisan backup:run

3. cd dulu jika script bergantung pada direktori kerja:

0 2 * * * cd /opt/scripts && ./backup.sh

4. Escape tanda %. Di crontab, % berarti baris baru (sisanya dikirim sebagai stdin). Ini menjebak saat memakai date:

# SALAH: perintah terpotong di %
0 1 * * * tar czf /backup/www-$(date +%F).tgz /var/www

# BENAR
0 1 * * * tar czf /backup/www-$(date +\%F).tgz /var/www

Cara paling rapi: taruh logika di skrip terpisah dan cron hanya memanggil skrip itu.

#!/usr/bin/env bash
# /usr/local/bin/backup-db.sh
set -euo pipefail
export PATH=/usr/local/bin:/usr/bin:/bin

ts=$(date +%F_%H%M)
mysqldump --single-transaction toko | gzip > "/backup/toko_${ts}.sql.gz"
find /backup -name 'toko_*.sql.gz' -mtime +14 -delete
chmod +x /usr/local/bin/backup-db.sh

Untuk mereproduksi kondisi cron saat debugging:

env -i SHELL=/bin/sh PATH=/usr/bin:/bin HOME=$HOME /bin/sh -c '/usr/local/bin/backup-db.sh'

5. Logging

Secara default, output job dikirim lewat email lokal ke pemilik crontab (via MAILTO). Di server tanpa MTA, output itu hilang begitu saja. Arahkan output ke file:

0 2 * * * /usr/local/bin/backup-db.sh >> /var/log/backup-db.log 2>&1
  • >> menambahkan ke file (bukan menimpa).
  • 2>&1 ikut menangkap stderr (pesan error). Urutannya penting: 2>&1 harus setelah redirect stdout.

Alternatif: kirim ke journald/syslog dengan tag, lalu baca pakai journalctl:

0 2 * * * /usr/local/bin/backup-db.sh 2>&1 | logger -t backup-db
journalctl -t backup-db --since today

Memeriksa apakah cron benar-benar menjalankan job:

grep CRON /var/log/syslog
# atau
journalctl -u cron --since "1 hour ago"

Pasang juga logrotate untuk file log yang terus bertambah.


6. Mencegah Job Tumpang Tindih

Jika job setiap 5 menit kadang berjalan lebih dari 5 menit, dua instance akan berjalan bersamaan. Gunakan flock:

*/5 * * * * flock -n /tmp/sync.lock /usr/local/bin/sync.sh >> /var/log/sync.log 2>&1

-n membuat instance kedua langsung keluar jika lock masih dipegang instance pertama.


7. Cron vs systemd Timer

AspekCronsystemd timer
KesederhanaanSatu barisDua file (.service + .timer)
LoggingManual (redirect/logger)Otomatis ke journald (journalctl -u)
Job terlewat saat server matiHilangPersistent=true menjalankannya setelah boot
Mencegah tumpang tindihManual (flock)Otomatis: service yang sedang aktif tidak dimulai dua kali
ResolusiMenitHingga detik
Batasan resource (CPU/memori)Tidak adaCPUQuota=, MemoryMax=, dll.
DependensiTidak adaAfter=, Requires= (misal tunggu network/mount)
JitterTidakRandomizedDelaySec=
PortabilitasSemua Unix, termasuk macOSHanya sistem ber-systemd
Melihat jadwal berikutnyaHitung sendirisystemctl list-timers

Rekomendasi: cron tetap bagus untuk tugas sederhana dan cepat dibuat. Untuk job penting di server (backup, sinkronisasi), systemd timer memberi logging dan keandalan lebih baik. Cara membuatnya ada di catatan Dasar systemd .


8. Checklist Debug “Cron Tidak Jalan”

  1. Service cron hidup? systemctl status cron
  2. Job terpanggil? grep CRON /var/log/syslog
  3. Pakai path absolut untuk semua binary dan file?
  4. % sudah di-escape?
  5. Skrip executable (chmod +x) dan punya shebang?
  6. Nama file di /etc/cron.d/ tanpa titik, dan ada kolom user?
  7. Baris terakhir crontab diakhiri newline? (cron bisa mengabaikan baris terakhir tanpa newline)
  8. Zona waktu server sesuai? Cek timedatectl; cron memakai zona waktu sistem.
  9. Output sudah diarahkan ke log untuk melihat pesan error?

Referensi

Hey! I’m Fanny, the software engineer tending to this digital garden. You can read more about me, or subscribe by email.

Comments