Uptime Kuma: Monitoring Status dengan Docker
Jalankan Uptime Kuma di Docker untuk memantau situs, port, DNS, dan cron job. Dapatkan alert lewat email atau Telegram, lalu publikasikan status page dari VPS terpisah.
Yang Anda bangun
Satu container kecil yang memantau server dan situs web lain dari luar, lalu segera memberi tahu Anda melalui email, Telegram, Discord, atau webhook ketika salah satunya berhenti merespons. Uptime Kuma adalah satu proses Node yang menggunakan file SQLite, sehingga dapat berjalan dengan baik pada RAM 256-512 MB serta menyediakan dashboard langsung, grafik riwayat, dan halaman status publik. Instalasinya cukup menggunakan file Compose yang terdiri dari sepuluh baris. Hal yang paling penting adalah di mana Anda menjalankannya dan apakah alert pernah aktif dalam pengujian, karena monitor yang belum pernah Anda buktikan dapat menghubungi Anda lebih buruk daripada tidak memiliki monitor sama sekali: monitor tersebut membuat Anda merasa terlindungi, padahal tidak memantau apa pun.
Jalankan monitor di lokasi yang tidak dapat terdampak oleh gangguan
Keputusan ini menentukan keberhasilan seluruh sistem, jadi lakukan terlebih dahulu. Jangan jalankan Uptime Kuma pada server yang sama dengan layanan yang dipantaunya. Jika monitor berada di server yang dipantau, kejadian yang ingin Anda deteksi—server tersebut mati atau kehabisan memori—juga akan menghentikan monitor. Akibatnya, tidak ada alert sama sekali: tidak adanya respons dari monitor yang mati terlihat sama persis dengan kondisi “semuanya baik-baik saja”. Ada jebakan lain ketika server masih aktif: monitor yang diarahkan ke localhost berbagi CPU dengan workload. Lonjakan beban dapat membuat pemeriksaannya sendiri mengalami timeout dan mengubah status target menjadi down. Ini menghasilkan alarm palsu, sementara pengguna sebenarnya tetap dapat mengakses layanan.
Karena itu, jalankan Uptime Kuma pada VPS yang berbeda dari server yang dipantaunya. Idealnya, gunakan provider atau region yang berbeda. Akses layanan dengan cara yang sama seperti pengguna, yaitu melalui Internet publik menggunakan hostname. Instance murah sudah cukup, dan satu VPS kecil untuk monitoring dapat memantau semua server Anda. Pemisahan ini paling penting untuk aplikasi berat yang Anda host. Misalnya, library foto PhotoPrism atau Immich dapat menggunakan CPU selama berjam-jam ketika mengindeks impor baru. Monitor yang menggunakan hardware yang sama akan melaporkan layanan sebagai down, padahal layanan tersebut hanya sedang sibuk. Untuk mendeteksi jika Kuma sendiri mati, tambahkan heartbeat push dari cron di lokasi lain.
Prasyarat dan penentuan kapasitas
- VPS Ubuntu 24.04 baru dengan Docker Engine dan plugin Compose v2 yang diinstal dari repositori apt milik Docker, bukan paket distro
docker.iokarena versinya tertinggal. - RAM 256 MB cukup untuk menjalankan beberapa monitor; 512 MB hingga 1 GB nyaman untuk puluhan monitor ditambah reverse proxy, dan penggunaan CPU hampir idle di antara pemeriksaan.
- Domain dan record DNS
A(misalnyastatus.example.comyang mengarah ke VPS), hanya jika Anda menginginkan TLS dan halaman status publik. Instance privat dapat melewati DNS dan menggunakan VPN atau tunnel SSH. - Jaringan keluar ke tujuan pengiriman alert: SMTP ke penyedia email Anda, atau HTTPS ke Telegram dan Discord.
File Compose
Masukkan ini ke dalam /srv/uptime-kuma/compose.yaml.
services:
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
restart: unless-stopped
ports:
- "127.0.0.1:3001:3001"
volumes:
- kuma-data:/app/data
volumes:
kuma-data:Jalankan dan pantau boot pertama:
sudo mkdir -p /srv/uptime-kuma
# save the file above as /srv/uptime-kuma/compose.yaml, then:
cd /srv/uptime-kuma && sudo docker compose up -d
sudo docker compose logs -f uptime-kumaStart yang benar mencatat Listening on 3001 lalu tidak menghasilkan log tambahan. Tiga hal dalam file tersebut ditetapkan secara sengaja.
127.0.0.1:3001:3001, bukan 3001:3001. Docker menerbitkan port menggunakan aturan DNAT yang dievaluasi sebelum ufw melihat paket tersebut. Karena itu, 3001:3001 tanpa konfigurasi tambahan akan menempatkan dashboard Anda di Internet publik, apa pun konfigurasi firewall Anda. Binding ke loopback membuatnya tetap privat dan hanya reverse proxy yang terekspos. Instance privat dapat melewati proxy dan mengakses 3001 melalui VPN WireGuard yang di-host sendiri.
Volume bernama di /app/data. Semua data yang diingat Uptime Kuma—database SQLite, monitor, pengaturan notifikasi, dan logo halaman status—disimpan di sana. Jika volume tersebut hilang, Anda akan memulai dari layar admin kosong. Volume ini adalah satu-satunya hal yang wajib dicadangkan.
Image menggunakan tag major, :2. Itu adalah lini stable saat ini. Periksa Docker Hub untuk major terbaru sebelum menyalin konfigurasi tersebut. Jangan pernah mengikuti tag yang dapat berubah seperti latest, karena tag tersebut sudah tidak digunakan oleh proyek. Lompatan versi major pada image ini merupakan migrasi database satu arah yang harus dipicu secara sengaja, bukan terjadi tanpa disadari saat pull rutin.
Satu catatan penting: /app/data harus berada pada filesystem yang mendukung file lock POSIX. Volume Docker lokal dapat digunakan. Pada NFS, database SQLite dapat rusak dan Anda akan mendapatkan SQLITE_BUSY serta database disk image is malformed. Karena itu, jangan pernah menggunakan network share.
Jalankan untuk pertama kali: buat akun admin
Buka instance melalui proxy Anda di https://status.example.com, atau melalui tunnel SSH: jalankan ssh -L 3001:127.0.0.1:3001 user@your-vps lalu buka http://localhost:3001. Halaman pertama adalah formulir penyiapan untuk username dan password administrator; tidak ada login default. Gunakan password yang kuat: dashboard ini dapat melihat alamat internal dan token semua hal yang Anda monitor. Jika nanti lupa, lakukan reset dari host, bukan dari browser:
sudo docker compose exec uptime-kuma npm run reset-passwordTambahkan saluran notifikasi terlebih dahulu, lalu uji
Siapkan peringatan sebelum menambahkan monitor agar Anda dapat melampirkan saluran saat membuatnya. Buka Settings then Notifications then Setup Notification, lalu gunakan tombol Test pada setiap saluran untuk memastikan pesan diterima. Notifikasi yang tidak diuji merupakan penyebab umum kedua kegagalan setup secara diam-diam.
Email (SMTP). Isi host, port, encryption, username, password, From, dan To. Dua kombinasi yang berfungsi adalah 465 dengan "Secure" disetel ke TLS/SSL, atau 587 dengan STARTTLS. Untuk Gmail dan sebagian besar provider yang menggunakan autentikasi dua faktor, Anda harus membuat app password; password akun biasa akan menghasilkan Error: Invalid login: 535-5.7.8 Username and Password not accepted.
Telegram. Kirim pesan @BotFather, kirim /newbot, lalu salin bot token. Untuk mendapatkan chat ID, kirim pesan kepada bot baru tersebut sekali, buka https://api.telegram.org/bot<token>/getUpdates, lalu baca chat.id dari JSON. Bot yang belum pernah menerima pesan terlebih dahulu memiliki getUpdates yang kosong dan tidak memiliki tujuan untuk mengirim pesan.
Discord. Di channel, buka Edit Channel then Integrations then Webhooks then New Webhook, salin URL, lalu tempelkan sebagai notifikasi Discord.
Generic webhook. Untuk kebutuhan lain, seperti incoming webhook Slack, endpoint khusus, atau hook otomasi rumah, tipe Webhook mengirim payload JSON melalui POST ke URL yang Anda berikan. Integrasi Apprise yang disertakan mencakup sebagian besar dari sekitar sembilan puluh layanan lain dalam daftar. Jika Anda tidak ingin ada pihak ketiga di antara outage dan ponsel Anda, pilih tipe bawaan ntfy dan arahkan ke server ntfy yang Anda kelola sendiri. Server tersebut mengirim notifikasi ke ponsel melalui channel yang sepenuhnya Anda kendalikan.
Tambahkan monitor, satu jenis setiap kali
Klik Add New Monitor, pilih jenisnya, lalu atur Friendly Name, Check Interval (60 seconds adalah nilai yang wajar), Retries (jumlah kegagalan berturut-turut sebelum status menjadi "down"; gunakan 2 atau 3 agar satu paket yang hilang tidak memicu notifikasi), serta notifikasi yang akan dikirim. Jenis yang akan Anda gunakan:
- HTTP(s). URL lengkap. Status dianggap aktif jika kode status diterima (200-299 secara default; perluas rentangnya di Accepted Status Codes jika
301atau401merupakan kondisi normal bagi Anda). Ini adalah pemeriksaan utama untuk situs web dan API. - HTTP(s) - Keyword. Permintaannya sama, tetapi status "up" juga mengharuskan suatu string ada, atau dengan Invert tidak ada, di dalam body. Pemeriksaan ini mendeteksi situs yang mengembalikan
200 OKtetapi menampilkan "Error establishing a database connection", yang akan dianggap sehat oleh pemeriksaan HTTP biasa. Pemeriksaan ini juga tepat untuk frontend browser yang berkomunikasi dengan backend terpisah, seperti skin toko video Halcyon di atas Jellyfin, yang shell halamannya dengan normal mengembalikan200meskipun server media di belakangnya tidak dapat dijangkau. - TCP Port. Koneksi TCP langsung ke host dan port, untuk layanan yang bukan HTTP: SSH pada 22, Postgres pada 5432, server SMTP pada 25, atau server game.
- Ping. Echo ICMP untuk memeriksa keterjangkauan dan latensi dengan biaya rendah. Namun, banyak jaringan dan firewall cloud memblokir ICMP. Karena itu, monitor ping berstatus merah dapat berarti "host down" atau "provider memblokir ping". Konfirmasikan dengan monitor TCP.
- DNS. Menyelesaikan record (A, AAAA, MX, TXT, dan sebagainya) melalui resolver yang Anda tentukan, serta dapat memverifikasi jawabannya. Dengan demikian, gangguan registrar atau DNS dapat terdeteksi lebih awal.
- Push. Monitor dari dalam ke luar, yang dibahas berikutnya.
Memantau cron job dengan monitor push (heartbeat)
Setiap monitor di atas memeriksa service Anda dari luar. Monitor push bekerja sebaliknya: Uptime Kuma menunggu, lalu job Anda memanggilnya untuk menyatakan bahwa job telah berjalan. Ini satu-satunya cara yang andal untuk memantau backup atau cron: pemeriksaan HTTP hanya mengetahui bahwa URL merespons, sedangkan hanya job yang mengetahui bahwa prosesnya selesai.
Buat monitor dengan tipe Push. Uptime Kuma akan membuat URL unik seperti:
https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=OK&ping=Atur Heartbeat Interval sesuai frekuensi job berjalan, lalu tambahkan satu baris di akhir script agar pemanggilan hanya dilakukan jika job berhasil:
#!/usr/bin/env bash
set -euo pipefail
# ... your backup or job runs here; set -e aborts on any failure ...
curl -fsS --retry 3 "https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=backup+ok&ping="Jika job gagal, set -e menghentikan proses sebelum curl dijalankan. Jika server tidak aktif, perintah tersebut juga tidak pernah dijalankan. Dalam kedua kasus, heartbeat berhenti. Setelah interval ditambah jendela percobaan ulang terlewati, Uptime Kuma mengubah status monitor menjadi down dan mengirimkan alert. Perlakukan token push tersebut sebagai rahasia: siapa pun yang memilikinya dapat memalsukan heartbeat yang sehat.
Bangun halaman status publik
Halaman status adalah tampilan yang ditujukan kepada pelanggan. Halaman ini menampilkan layanan yang aktif beserta riwayat terbarunya tanpa mengekspos dashboard Anda. Buka Status Pages lalu New Status Page, masukkan nama dan slug (path publik, seperti /status/main), seret monitor yang diinginkan ke dalam grup seperti "Websites" dan "APIs", tambahkan logo dan deskripsi singkat, lalu klik Save. Anda juga dapat mengaitkan halaman tersebut dengan domainnya sendiri agar status.example.com menyajikannya secara langsung.
Perhatikan dua hal. Tambahkan hanya monitor yang memang boleh dipublikasikan, karena halaman status mengungkapkan bahwa suatu layanan tersedia dan menunjukkan apakah layanan tersebut aktif. Dashboard tetap dilindungi login Anda, sedangkan halaman status memang bersifat publik dan tidak memerlukan autentikasi.
Pasang di belakang reverse proxy dengan TLS, dan perhatikan WebSocket
Untuk instance publik, pasang reverse proxy di depan container yang terikat ke loopback agar TLS dan hostname dapat digunakan. Detail yang sering terlewat adalah: UI Uptime Kuma merupakan aplikasi Socket.IO yang berjalan secara real-time, sehingga proxy harus meng-upgrade koneksi WebSocket. Jika bagian ini terlewat, halaman tetap dimuat tetapi tidak pernah terhubung; dashboard berhenti pada status "Connecting...", heartbeat langsung tidak pernah diperbarui, dan konsol browser menampilkan WebSocket connection to 'wss://.../socket.io/...' failed.
Install nginx dan certbot, lalu tulis vhost yang melakukan proxy ke port loopback. Gunakan port 80 untuk sementara dan biarkan certbot menambahkan TLS setelahnya; challenge, timer renewal, dan mode kegagalannya dibahas dalam menerbitkan sertifikat Let's Encrypt dengan certbot dan nginx.
sudo apt install -y nginx certbot python3-certbot-nginxSimpan konfigurasi ini sebagai /etc/nginx/sites-available/status.example.com; dua baris WebSocket adalah bagian yang penting:
server {
listen 80;
server_name status.example.com;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
}
}Aktifkan site, uji konfigurasi, lalu biarkan certbot menulis ulang blok tersebut agar mendengarkan pada port 443, memasang sertifikat, dan menambahkan redirect HTTP-ke-HTTPS:
sudo ln -s /etc/nginx/sites-available/status.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d status.example.comPasangan Upgrade dan Connection "upgrade" adalah bagian utama konfigurasi, sedangkan proxy_read_timeout 3600s mencegah nginx memutus socket yang berjalan dalam waktu lama; certbot menyalin keduanya ke blok 443 yang dibuatnya. Jika Anda sudah menjalankan beberapa container di belakang satu proxy, merutekannya melalui Traefik dengan TLS otomatis memberikan hasil yang sama menggunakan label container dan secara default meneruskan upgrade WebSocket.
Jangan gunakan basic authentication pada seluruh vhost, karena itu juga akan mengunci halaman status publik dan endpoint /api/push. Tetap gunakan login bawaan Uptime Kuma, tambahkan fail2ban untuk memantau login gagal berulang jika layanan tersebut menghadap Internet, dan jika dashboard tidak perlu bersifat publik, hapus proxy lalu akses dashboard melalui VPN.
Pemantauan kedaluwarsa sertifikat yang benar
Monitor HTTP(s) juga dapat memperingatkan Anda sebelum sertifikat TLS kedaluwarsa: centang Certificate Expiry Notification, lalu Uptime Kuma akan mengirim peringatan beberapa hari sebelum tanggal kedaluwarsa. Dua kesalahan dapat menyebabkan hasil pembacaan yang keliru. Gunakan hostname, bukan IP, saat memantau, karena permintaan tanpa SNI akan menerima sertifikat default server dan menampilkan Hostname/IP does not match certificate's altnames. Jangan centang Ignore TLS/SSL Error pada monitor yang ingin digunakan untuk menerima peringatan kedaluwarsa. Opsi tersebut ditujukan untuk host internal dengan sertifikat self-signed (unable to verify the first certificate, DEPTH_ZERO_SELF_SIGNED_CERT), tetapi membuat Uptime Kuma tidak memeriksa sertifikat sama sekali, termasuk tanggal kedaluwarsanya.
Cadangan: hanya ada satu direktori
Karena semua data berada di /app/data, cadangan adalah salinan volume yang dibuat saat container dihentikan. Dengan demikian, file SQLite berada dalam kondisi konsisten:
cd /srv/uptime-kuma
sudo docker compose stop
sudo docker run --rm \
-v uptime-kuma_kuma-data:/data \
-v /var/backups/kuma:/backup \
alpine tar czf /backup/kuma-$(date -u +%Y%m%dT%H%M%SZ).tgz -C /data .
sudo docker compose startPastikan nama sebenarnya volume dengan docker volume ls | grep kuma terlebih dahulu, karena Compose menambahkan awalan berupa direktori proyek. Kemudian salin arsip tar tersebut ke luar server, karena cadangan pada VPS yang sama hanyalah salinan, bukan cadangan. Pemulihan dilakukan secara terbalik: hentikan stack, ekstrak ke volume /app/data yang kosong, lalu jalankan stack.
Peningkatan Versi
Peningkatan versi dilakukan dengan menarik image:
cd /srv/uptime-kuma
sudo docker compose pull
sudo docker compose up -dContainer baru akan menjalankan migrasi database saat pertama kali dimulai; pantau docker compose logs -f. Buat backup yang dijelaskan di atas sebelum melakukan pull, dan gunakan tag major yang sama: perpindahan dari :1 ke :2 merupakan migrasi satu arah, jadi buat backup terlebih dahulu dan periksa catatan rilis.
Mode kegagalan dan string yang akan Anda lihat
Status "down" palsu pada monitor yang diarahkan ke localhost. Monitor berubah merah dengan timeout of 48000ms exceeded atau connect ETIMEDOUT, tetapi service merespons dari laptop Anda. Jika monitor menargetkan host yang sama dengan tempat Uptime Kuma berjalan, lonjakan CPU atau memori menyebabkan pemeriksaan tidak memperoleh cukup sumber daya, bukan target yang bermasalah. Pindahkan monitor ke VPS terpisah dan targetkan hostname publik.
connect ECONNREFUSED 127.0.0.1:443 (atau port apa pun). Tidak ada proses yang mendengarkan pada port tersebut: service sedang down, atau Anda memantau localhost dari dalam container, tempat 127.0.0.1 adalah container, bukan server Anda. Pantau hostname publik, bukan loopback.
Invalid login: 535-5.7.8 Username and Password not accepted pada pengujian email. Kredensial SMTP salah, atau provider mengharuskan kata sandi khusus aplikasi tetapi Anda memasukkan kata sandi akun. Buat kata sandi aplikasi, lalu masukkan kata sandi tersebut.
connect ETIMEDOUT atau queryA ETIMEDOUT <host> pada pengujian email. Port salah, atau provider memblokir SMTP keluar. Pastikan 465 atau 587 sesuai dengan pengaturan Secure/STARTTLS, lalu uji dari host menggunakan nc -vz smtp.example.com 587. Banyak provider memblokir 25 keluar, dan beberapa provider memblokir port submission sampai Anda memintanya.
self signed certificate atau unable to verify the first certificate pada pengujian email. Server SMTP Anda menyajikan sertifikat yang tidak dipercayai Node; perbaiki sertifikat mail server, bukan menutupi masalahnya.
Dashboard berhenti pada "Connecting...", dan konsol menampilkan WebSocket connection ... failed. Reverse proxy tidak melakukan upgrade WebSocket. Tambahkan header Upgrade dan Connection "upgrade" pada nginx, atau gunakan proxy yang meneruskan header tersebut secara default, seperti Traefik atau Caddy. HTML tetap dimuat karena itu adalah HTTP GET biasa; hanya socket aktif yang memerlukan upgrade.
Monitor masa berlaku sertifikat tidak pernah memberikan peringatan, atau memberikan peringatan yang salah. Opsi Ignore TLS/SSL Error mungkin dicentang sehingga pemeriksaan sertifikat dinonaktifkan, atau monitor menargetkan IP dan membaca sertifikat yang salah karena SNI tidak tersedia, lalu menampilkan Hostname/IP does not match certificate's altnames. Hapus centang pada opsi pengabaian tersebut dan pantau berdasarkan hostname.
SQLITE_BUSY atau database disk image is malformed di log. Volume /app/data berada pada filesystem tanpa penguncian file yang semestinya, biasanya NFS; pindahkan volume tersebut ke volume Docker lokal dan pulihkan dari backup.
FAQ
Di mana saya harus menjalankan monitor uptime?
Jalankan pada server yang berbeda dari server yang dipantaunya, idealnya pada provider atau region lain, lalu akses server tersebut melalui hostname di Internet publik seperti yang dilakukan pengguna Anda. Jika monitor berada pada mesin yang sama dengan targetnya, gangguan yang mematikan server juga akan mematikan monitor. Host yang kelebihan beban juga dapat membuat monitor melaporkan layanan yang sebenarnya normal sebagai "down". VPS kecil yang terpisah menghindari kedua masalah tersebut.
Bagaimana cara menerima alert melalui Telegram atau email?
Tambahkan channel pada Settings then Notifications, lalu kaitkan channel tersebut dengan setiap monitor. Untuk Telegram, buat bot menggunakan @BotFather dan baca chat.id dari https://api.telegram.org/bot<token>/getUpdates. Untuk email, gunakan 465 untuk SSL atau 587 untuk STARTTLS, serta app password jika provider Anda menggunakan autentikasi dua faktor. Tekan Test dan pastikan pesan diterima sebelum mengandalkannya.
Apakah Uptime Kuma dapat memantau cron job atau script backup?
Ya. Gunakan monitor Push: Uptime Kuma memberikan URL, lalu Anda curl URL tersebut pada akhir script agar notifikasi hanya dikirim jika script berhasil. Jika job gagal atau server tidak aktif, heartbeat tidak pernah diterima dan Anda akan menerima alert setelah interval berakhir. Ini adalah satu-satunya cara yang andal untuk memastikan scheduled job benar-benar berjalan, karena pemeriksaan eksternal tidak dapat melihat proses internalnya.
Uptime Kuma vs Zabbix, mana yang harus saya jalankan?
Uptime Kuma menjawab pertanyaan "apakah layanan aktif, dari sisi eksternal, dan apakah alert sudah dikirim kepada saya" dalam sepuluh menit dengan penggunaan resource yang hampir tidak ada, serta menyediakan status page. Uptime Kuma tidak mengumpulkan metrik mendalam seperti tren CPU, memori, dan disk, atau threshold untuk seluruh fleet. Untuk kebutuhan tersebut, server monitoring Zabbix lengkap adalah tool berbasis agent yang lebih berat, dan banyak orang menjalankan keduanya. Masih menentukan apa yang akan dijalankan? rangkuman kami tentang layanan yang dapat di-self-host pada 2026 menempatkan monitoring dalam konteksnya.