Halo Sobat Online! Pernah tidak, Anda baru sadar backup gagal setelah butuh datanya? Cara paling aman untuk pantau cron job di VPS adalah kebalikan dari yang biasa kita pakai: bukan skripnya yang melapor saat sukses, tapi ada penjaga yang berteriak kalau laporan itu tidak pernah datang. Alatnya bernama Healthchecks, bisa dipasang sendiri di VPS, dan gratis.
Analoginya seperti satpam ronda yang wajib menelepon pos setiap satu jam. Selama telepon datang tepat waktu, semua tenang. Begitu satu jam lewat tanpa kabar, pos langsung tahu ada yang tidak beres — entah satpamnya jatuh, atau jaringannya putus. Itulah pola dead man’s switch, dan di dunia server pola ini menangkap masalah yang paling sering luput: VPS reboot, skrip error, disk penuh, sampai cron daemon yang diam-diam tidak jalan.
Kenapa Cron Job Bisa Gagal Tanpa Kita Sadari
Anda mungkin berpikir, “kan sudah ada MAILTO di crontab.” Betul, tapi cara itu punya tiga lubang:
- Butuh MTA yang sudah dikonfigurasi. Kalau tidak ada, email peringatan tidak pernah terkirim ke mana-mana.
- Tidak berguna kalau mesinnya mati. VPS reboot atau kehilangan jaringan berarti cron tidak jalan sama sekali — dan tidak ada yang melapor.
- Gampang bikin telinga kebal. Setiap output skrip memicu email, jadi peringatan penting tenggelam di antara pesan rutin.
Padahal kegagalan yang paling berbahaya justru yang sunyi: perintah rsync yang berhenti di tengah, sertifikat yang gagal diperbarui, atau dump database yang hasilnya 0 byte.
Kenapa Harus Pantau Cron Job di VPS dengan Healthchecks?
Healthchecks adalah aplikasi open-source (Python + Django) untuk memantau pekerjaan terjadwal dengan pola heartbeat monitoring. Skrip Anda mengirim satu permintaan HTTP (“ping”) setiap kali selesai; Healthchecks mencatatnya dan mengirim notifikasi kalau ping berikutnya tidak muncul sesuai jadwal.
Yang membuatnya cocok dijalankan sendiri:
- Tidak butuh aplikasi tambahan di klien. Cukup
curlyang hampir selalu ada di VPS mana pun. - Satu instance untuk semua pekerjaan. Backup, sinkronisasi, laporan harian, deployment — semua bisa dipantau dari satu dasbor.
- Ringan. Aplikasi plus database SQLite cukup dengan 512 MB RAM; image Docker resminya tersedia untuk
amd64,arm64, danarm/v7. - Banyak jalur notifikasi. Email, Telegram, Gotify, ntfy, webhook, sampai Prometheus — sebaiknya pasang dua jalur sekaligus supaya tidak ikut gagal bersamaan.
Versi stabil terbaru saat artikel ini ditulis adalah v4.4 (31 Agustus 2026) yang sudah memakai Django 6.1. Catatan penting kalau Anda memakai PostgreSQL: rilis ini meninggalkan PostgreSQL di bawah versi 15, MySQL di bawah 8.4, dan MariaDB di bawah 10.11.
Yang Perlu Disiapkan
- VPS Linux (Ubuntu 22.04/24.04 atau Debian 12) dengan akses
sudo. 1 vCPU dan 1 GB RAM sudah lega untuk pemakaian pribadi. - Docker dan Docker Compose yang sudah terpasang. Cek dengan
docker --versiondandocker compose version. - Satu subdomain, misalnya
hc.domainku.com, yang A record-nya sudah diarahkan ke IP VPS. Port 80 dan 443 harus bebas. - Opsional: token bot Telegram kalau ingin notifikasi masuk ke chat atau grup.
Langkah 1: Siapkan Folder Proyek dan File .env
mkdir -p ~/healthchecks && cd ~/healthchecks
nano .env
Isi file .env dengan konfigurasi berikut, lalu ganti domain, nama bot, dan SECRET_KEY dengan milik Anda:
ALLOWED_HOSTS=hc.domainku.com
SITE_ROOT=https://hc.domainku.com
SITE_NAME=Healthchecks VPS Saya
DEBUG=False
REGISTRATION_OPEN=False
SECRET_KEY=ganti-dengan-50-karakter-acak-dari-password-manager
# database: SQLite sudah cukup untuk pemakaian pribadi
DB=sqlite
DB_NAME=/data/hc.sqlite
# notifikasi Telegram (opsional, bisa diisi belakangan)
TELEGRAM_BOT_NAME=nama_bot_anda_bot
TELEGRAM_TOKEN=123456789:token-dari-BotFather
Dua hal yang wajib diingat. Pertama, ALLOWED_HOSTS harus persis domain yang dipakai, kalau tidak dasbornya menolak dibuka. Kedua, rapatkan izin filenya karena isinya berisi kunci rahasia:
chmod 600 ~/healthchecks/.env
Langkah 2: Tulis docker-compose.yml
Buat file docker-compose.yml di folder yang sama, berisi dua layanan: Healthchecks sendiri dan Caddy sebagai pintu HTTPS otomatis.
services:
healthchecks:
image: healthchecks/healthchecks:v4.4
container_name: healthchecks
restart: unless-stopped
env_file: .env
volumes:
- hc-data:/data
caddy:
image: caddy:2
restart: unless-stopped
command: caddy reverse-proxy --from https://hc.domainku.com --to http://healthchecks:8000
ports:
- "80:80"
- "443:443"
volumes:
- caddy-data:/data
- caddy-config:/config
volumes:
hc-data:
caddy-data:
caddy-config:
Image resmi Healthchecks sudah menjalankan server web uWSGI sekaligus proses pengirim notifikasi di latar belakang, jadi Anda tidak perlu menjalankan apa pun secara terpisah. Yang tidak ditangani image ini adalah urusan TLS — itulah sebabnya Caddy ikut dipasang. Kalau Anda lebih nyaman dengan Nginx, pola pemasangannya sama seperti pada panduan Nginx reverse proxy di VPS plus HTTPS gratis, sedangkan versi Caddy yang lebih sederhana ada di artikel pasang Caddy di VPS.
Langkah 3: Nyalakan Container dan Buat Akun Admin
cd ~/healthchecks
docker compose up -d
docker compose logs -f healthchecks
Di log Anda akan melihat proses migrasi database berjalan otomatis saat container pertama kali menyala. Setelah baris log berhenti berderak, tekan Ctrl+C lalu buat akun admin:
docker compose exec healthchecks /opt/healthchecks/manage.py createsuperuser
Masukkan email, username, dan password saat diminta. Sekarang buka https://hc.domainku.com — Anda akan langsung disambut sertifikat HTTPS dari Caddy dan halaman login Healthchecks.
Langkah 4: Buat Check Pertama dan Ambil Ping URL
Di dasbor, pilih Add Check. Isi tiga hal yang menentukan perilaku alarmnya:
- Name — nama pekerjaannya, misalnya
Backup harian ke cloud. - Period — seberapa sering pekerjaan itu seharusnya berjalan, misalnya 1 hari.
- Grace Time — waktu tenggang tambahan sebelum alarm berbunyi.
Grace Time inilah kunci supaya alarm tidak gampang tersinggung. Kalau backup biasanya selesai dalam 10 menit, beri grace 30–60 menit: Healthchecks baru menyatakan “DOWN” ketika jadwalnya terlewat plus tenggang itu. Selama skrip masih berjalan, belum ada peringatan.
Setelah check tersimpan, Healthchecks menampilkan ping URL berbentuk seperti ini:
https://hc.domainku.com/ping/9f8c1d2e-7a44-4b31-9c02-1e5d7aa93b10
URL itu bersifat rahasia seperti password: siapa pun yang tahu bisa memalsukan laporan “semua aman”. Simpan di password manager, dan jangan pernah ditempel di dokumentasi publik.
Langkah 5: Sambungkan ke Cron Job
Sekarang bagian yang membuat semuanya berguna. Misalkan Anda punya skrip backup seperti pada panduan backup VPS otomatis ke cloud pakai rclone. Tambahkan ping di baris terakhir, plus set -e di awal skrip:
#!/usr/bin/env bash
set -euo pipefail
PING="https://hc.domainku.com/ping/9f8c1d2e-7a44-4b31-9c02-1e5d7aa93b10"
rclone copy /root/backup remote:backup-vps
curl -fsS -m 10 --retry 5 -o /dev/null "$PING"
Kenapa set -e penting? Karena kalau rclone gagal di tengah jalan, skrip berhenti sebelum baris ping dijalankan. Ping tidak pernah datang, dan Healthchecks memberi alarm setelah grace time lewat. Inilah bedanya dengan pola lama yang hanya melapor saat sukses.
Kalau Anda lebih suka merangkai di crontab tanpa mengubah skrip, polanya seperti ini:
# jalankan backup pukul 02.00, kirim ping hanya kalau sukses
0 2 * * * root /usr/local/bin/backup-vps.sh && curl -fsS -m 10 --retry 5 -o /dev/null https://hc.domainku.com/ping/9f8c1d2e-7a44-4b31-9c02-1e5d7aa93b10
Tanda && berarti ping dikirim hanya bila skrip keluar dengan status 0. Opsi -f membuat curl menganggap balasan selain HTTP 200 sebagai error, -m 10 membatasi waktu tunggu 10 detik, --retry 5 mencoba ulang saat jaringan tersendat, dan -o /dev/null menyembunyikan output. Kirim juga vonis cepat saat skrip tahu dirinya gagal, dengan menambahkan akhiran /fail:
curl -fsS -m 10 --retry 3 -o /dev/null "$PING/fail"
Anda bahkan bisa menempelkan status keluarnya langsung, misalnya "$PING/$?", sehingga dasbor mencatat kode error yang sebenarnya. Untuk pekerjaan yang berjalan lama, kirim sinyal start di awal agar Healthchecks bisa mengukur durasinya, dan kalau ingin membawa bukti, kirim isi log lewat body POST.
Langkah 6: Aktifkan Notifikasi Telegram
Notifikasi berbasis email sudah aktif begitu SMTP diisi, tapi untuk peringatan yang benar-benar terbaca di kantong, Telegram jauh lebih cepat. Kredensialnya diisi di sisi server (sudah kita siapkan di .env): TELEGRAM_BOT_NAME dan TELEGRAM_TOKEN.
Setelah .env diubah, terapkan ulang:
docker compose up -d
Integrasi Telegram lalu muncul di halaman Integrations pada proyek Anda. Aktifkan, arahkan ke chat atau grup tujuan, dan selesai. Sebaiknya tambahkan satu jalur kedua — misalnya email atau webhook — karena redundansi adalah alasan utama kenapa pola heartbeat ini bisa dipercaya.
Langkah 7: Uji Coba — Pastikan Alarmnya Benar-Benar Berbunyi
Monitoring yang belum pernah diuji sama saja dengan tidak ada monitoring. Ada dua uji murah:
- Uji jalur sukses. Jalankan perintah ping secara manual dan lihat check berpindah ke status “up” dengan keterangan waktu terakhir ping di dasbor.
- Uji jalur gagal. Buat satu check percobaan dengan Period 5 menit dan grace time sekecil mungkin, lalu jangan kirim ping apa pun. Dalam beberapa menit Anda harus menerima notifikasi DOWN. Kalau notifikasinya tidak masuk, masalahnya ada di integrasi — bukan di skrip backup.
Jangan lupa hapus check percobaan itu setelah selesai supaya dasbor tetap bersih.
Tips supaya Alarm Tidak Jadi Alarm Palsu
- Selalu batasi waktu dan ulangi ping.
-m 10 --retry 5sudah menutup jaringan yang tersendat, sumber alarm palsu paling umum. - Beri grace time di atas durasi normal. Untuk job yang kadang mengantre lama, grace time 30–60 menit jauh lebih nyaman daripada peringatan tiap hari.
- Cek zona waktu server. Ping yang konsisten maju atau mundur satu jam biasanya bukan bug, melainkan perbedaan zona waktu. Lihat dengan
timedatectl status. - Satu check, satu pekerjaan. Menggabungkan lima skrip dalam satu ping membuat Anda tahu ada yang gagal, tapi tidak tahu yang mana.
- Hati-hati pada job berinterval sangat pendek. Untuk pekerjaan yang jalan setiap menit, pemantauan berbasis heartbeat justru menambah bising; cukup andalkan log.
- Backup datanya sendiri.
hc.sqlitehidup di volumehc-data. Cukup salin volume itu (atau dump databasenya) secara berkala bersama berkas penting lain.
Kalau ingin memantau layanan yang harus selalu online dari sisi luar, misalnya website dan port SSH, tambahkan juga Uptime Kuma di VPS. Dua alat ini tidak saling meniadakan: Uptime Kuma menjaga layanan, Healthchecks menjaga pekerjaan terjadwal.
Kesimpulan
Backup yang gagal diam-diam adalah utang yang baru terasa saat Anda paling butuh datanya. Dengan Healthchecks self-hosted di VPS, Anda membalik logikanya: pekerjaan yang tidak melapor otomatis dianggap bermasalah, dan alarmnya berbunyi sebelum Anda sadar sendirian.
Mulailah dari satu pekerjaan yang paling penting — biasanya backup harian. Setelah jalur ping dan notifikasinya terbukti berbunyi, tambahkan sisanya satu per satu. Selamat mencoba, Sobat Online — semoga backup Anda membosankan karena selalu berhasil, dan kalau pun tidak, Anda jadi orang pertama yang tahu!

