Cara Monitoring Server: Uptime, Rollback, dan Backup
Cara monitoring server Docker: health check, uptime check, dan metrics, lalu rollback rilis yang rusak lewat tag image-nya dan uji restore backup Anda.
Oleh Matthews WongDitinjau pada
Poin utama
Monitoring container Docker berarti mengawasinya dari tiga sisi: health check milik container itu sendiri, uptime check dari luar, dan metrics dari waktu ke waktu. Monitoring hanya memberi tahu bahwa ada yang rusak. Pemulihannya adalah rollback, yaitu menjalankan lagi image sebelumnya lewat tag yang immutable. Backup menjaga hal yang tidak bisa dikembalikan oleh rollback: data.
Setelah pelajaran ini, Anda bisa
- Membedakan health check, uptime check, dan metrics, serta apa yang ditangkap masing-masing.
- Me-rollback rilis yang rusak ke tag image sebelumnya, dan menjelaskan kenapa mendeteksi kegagalan belum berarti pulih darinya.
- Menentukan apa yang perlu di-backup di satu server, lalu membuktikannya dengan restore.
Ikuti diagramnya langkah demi langkah
Tekan Putar, atau melangkah dengan panah. Setiap langkah juga ditulis di bawah diagram.
Rilis bermasalah: siapa yang tahu duluan, dan cara membatalkannya
v2 di-deploy, health check-nya gagal sementara v2 tetap melayani pengunjung, uptime check dari luar mengirim alert, dan menjalankan lagi tag image sebelumnya memulihkan layanan.
Tombol: ← → langkah · Home / End · K putar atau jeda
Dua image ber-tag, satu server, dan dua pengawas. Health check Docker berjalan di dalam container web; Uptime Kuma memeriksa aplikasi yang sama dari luar, lewat jalur yang dipakai pengunjung.
Deploy mengarahkan IMAGE ke tag v2 lalu menjalankan Compose, yang mengganti container v1 dengan container v2. Build-nya lolos, jadi semuanya tampak hijau.
IMAGE=devops-lab:v2 \ docker compose up -d --waitDi dalam container, /health kini menjawab 500. Setelah tiga kali gagal berturut-turut, Docker menandai v2 unhealthy dan --wait keluar dengan kode 1. Deploy yang pertama tahu, tetapi tidak me-rollback apa pun.
interval: 5s retries: 3Tebak langkah berikutnya v2 kini unhealthy. Apa yang didapat pengunjung? (Halaman error: Docker menghentikan v2 · Halaman dari v1, dialihkan otomatis · Halaman dari v2, seperti sebelumnya)Pengunjung tetap mendapat halaman dari v2. Unhealthy hanyalah label, bukan tombol mati: restart policy bereaksi saat proses berhenti, dan proses ini masih berjalan.
curl http://127.0.0.1:8080/ hello from v2Uptime Kuma memanggil /health dari luar, mendapat 500, lalu mengirim alert ke Anda. Tanpa --wait, seperti pada deploy situs ini, inilah peringatan pertama yang sampai ke manusia.
docker compose up -d --remove-orphansTebak langkah berikutnya Alert sudah masuk. Apa cara tercepat kembali ke v1? (Arahkan IMAGE ke v1, jalankan Compose lagi · Build ulang v1 dari source, lalu deploy)Rollback: arahkan IMAGE ke tag sebelumnya lalu jalankan Compose lagi. Tag itu menunjuk satu build yang pasti dan masih ada di disk, jadi tidak ada yang perlu di-build ulang.
IMAGE=devops-lab:v1 \ docker compose up -d --waitv1 lolos health check, --wait keluar dengan kode 0, dan probe kembali melaporkan up. Sekarang perbaiki v2 dengan tenang: rollback memberi waktu, bukan memperbaiki bug.
curl http://127.0.0.1:8080/ hello from v1
Apa beda health check, uptime check, dan metrics?
Health check berjalan di dalam container. Docker menjalankan sebuah perintah secara terjadwal, di sini request ke /health setiap beberapa detik, lalu menandai container sebagai healthy atau unhealthy. Murah dan cepat, tetapi hanya membuktikan bahwa proses menjawab di loopback-nya sendiri. Health check tidak bisa melihat DNS, TLS, reverse proxy, atau jaringan antara server Anda dan pengunjung.
Baca selengkapnya (3)Tutup
Uptime check memanggil URL publik Anda dari luar, seperti yang dilakukan pengunjung, dan memberi tahu seseorang saat URL itu berhenti menjawab. Uptime Kuma adalah tool self-hosted untuk tugas ini: monitor HTTP, TCP, ping, dan keyword, dengan notifikasi ke Telegram, Slack, email, dan banyak kanal lain. Jalankan di mesin lain, bukan di server yang diawasinya, supaya tidak ikut mati bersama hal yang seharusnya ia laporkan.
Metrics adalah angka dari waktu ke waktu: memori, CPU, jumlah request. Prometheus mengumpulkannya dengan menarik (pull) data lewat HTTP dari exporter secara terjadwal, node exporter untuk host dan cAdvisor untuk container, lalu Grafana menggambarnya menjadi dashboard. Pertanyaan yang dijawab metrics berbeda dari dua lainnya: bukan apakah aplikasi masih hidup, melainkan apakah kondisinya makin memburuk, misalnya memori yang pelan-pelan naik mendekati batas container sebelum di-kill oleh kernel.
Konfigurasi Prometheus, Grafana, dan Uptime Kuma milik situs ini ada di server, bukan di repository, jadi tidak publik dan tidak dikutip di pelajaran ini. Sebagai gantinya, semua tool di sini dijalankan di laptop Anda dari image resminya, dan panduan setup di bagian akhir membahas masing-masing langkah demi langkah.
Kenapa health check yang gagal tidak me-rollback apa pun?
Karena mendeteksi masalah dan memulihkannya adalah dua pekerjaan berbeda, dan Docker hanya mengerjakan yang pertama. Docker menandai container unhealthy setelah gagal sebanyak retries kali berturut-turut, dan itu hanya label. Prosesnya tetap berjalan dan tetap menjawab request, karena restart policy bereaksi saat proses berhenti, bukan pada status kesehatannya.
Baca selengkapnya (2)Tutup
docker compose up --wait membuat deploy ikut menyadarinya. Perintah ini menunggu service berjalan atau healthy, dan keluar dengan error saat ada yang unhealthy. Pada drill untuk pelajaran ini, v2 yang /health-nya menjawab 500 membuat --wait keluar dengan kode 1 setelah sekitar 19 detik, dengan jeda pengecekan 5 detik. Sementara itu curl tetap mendapat hello from v2. Rilisnya rusak dan live sekaligus.
Deploy situs ini menjalankan docker compose up -d tanpa --wait, jadi rilis yang gagal health check tetap membuat workflow selesai hijau. Menambahkan --wait mengubah kegagalan yang diam-diam menjadi run yang merah. Tetapi tetap tidak ada rollback: langkah itu tugas Anda, atau tugas sebuah script.
Bagaimana tag image yang immutable membuat rollback cepat?
Rollback berarti menjalankan lagi versi sebelumnya yang terbukti baik. Itu hanya cepat jika versi sebelumnya punya nama yang menunjuk tepat satu build. Tag latest ikut berpindah setiap kali push, jadi setelah deploy yang buruk, latest justru menunjuk build yang buruk itu. Tag immutable adalah tag yang tidak pernah dipakai ulang: beri setiap build tag berupa commit SHA-nya, maka tag itu selalu berarti build tersebut.
Baca selengkapnya (2)Tutup
Pipeline situs ini mem-push setiap image dua kali, sebagai latest dan sebagai commit SHA, lalu deploy menuliskan tag SHA itu ke .env di server sebagai IMAGE. Jadi versi yang live selalu satu build yang pasti, dan versi sebelumnya juga punya nama. Pembersihan setelah setiap deploy menyisakan image yang dibuat dalam 72 jam terakhir, jadi rollback ke rilis yang baru lewat bisa dimulai dari salinan yang sudah ada di disk.
Ada tiga jalan kembali, dari yang tercepat sampai yang paling mudah dilacak. Di server, ubah IMAGE ke tag sebelumnya lalu jalankan docker compose up -d --wait; deploy berikutnya menulis ulang .env, jadi anggap ini solusi sementara. Di GitHub, jalankan ulang (re-run) workflow terakhir yang berhasil, yang memakai commit SHA yang sama dan bisa dilakukan sampai 30 hari setelah run aslinya. Atau git revert commit yang bermasalah lalu push, yang melewati seluruh pipeline dan meninggalkan jejak audit.
Apa yang perlu di-backup di satu server, dan bagaimana menguji restore?
Mulailah dari pertanyaan di mana state disimpan, bukan dari isi disk. Untuk situs ini jawabannya: hampir tidak ada di server. Kode ada di git, setiap image ada di registry, dan konfigurasi ada di secrets dan variables GitHub, jadi server baru bisa dibangun ulang dari semua itu. Satu-satunya volume yang dipasang aplikasi berisi cache gambar yang bisa dibuat ulang, bukan data.
Baca selengkapnya (2)Tutup
Service lain berbeda. Tool monitoring menyimpan pengaturan dan riwayatnya di volume, dan database menyimpan semuanya di sana. Volume-volume itulah daftar backup Anda, dan karena itu pula pembersihan di situs ini tidak pernah menyentuh volume: prune volume akan menghancurkan datanya. Simpan minimal satu salinan di luar server, karena backup di disk yang sama ikut hilang bersama disk itu.
Backup yang belum pernah di-restore hanyalah harapan. Resep resmi Docker memasang volume ke container sekali pakai lalu menulis arsip tar ke folder di host; restore adalah kebalikannya, ke volume baru. Setelah itu jalankan salinan kedua service tersebut di atas volume hasil restore dan periksa apakah data Anda ada. Langkah terakhir itulah ujian yang sebenarnya.
Konfigurasi nyata di balik pelajaran ini
Kutipan dari repositori yang membangun dan men-deploy situs ini, apa adanya.
healthcheck:
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://127.0.0.1:3000/robots.txt",
]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"Dua instrumen pertama ada di file runtime itu sendiri. Setiap 30 detik Docker menjalankan wget BusyBox ke /robots.txt di dalam container, tiga kegagalan berturut-turut membuatnya unhealthy, dan start period 20 detik memberi Next.js waktu untuk boot. URL ringan seperti ini membuktikan server Node menjawab, bukan bahwa setiap halaman ter-render. Blok logging membatasi log tiap container di tiga file 10 MB, jadi log tidak bisa memenuhi disk.
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
${{ steps.meta.outputs.ref }}:latest
${{ steps.meta.outputs.ref }}:${{ github.sha }}Setiap image di-push dua kali, sebagai latest dan sebagai commit SHA. Job deploy menuliskan tag SHA itu ke .env di server sebagai IMAGE (baris 231), jadi versi yang berjalan selalu satu build yang pasti, begitu pula versi sebelumnya. Nama kedua yang tidak pernah dipakai ulang itulah seluruh mekanisme rollback-nya.
# Reclaim disk once the new container is serving.
#
# Every deploy pulls a fresh :<sha> tag, and a tagged image is not
# dangling, so the previous `docker image prune -f` never removed
# them — they accumulated on the VPS until the disk filled. `-a`
# drops the superseded tags too, while `until=72h` keeps the last
# few days so a rollback can still start from a local image.
#
# Images backing a running container are never removed, which is
# what keeps the other stacks on this box (<other services>)
# intact. Volumes are deliberately left alone —
# pruning those would destroy their data.
docker image prune -af --filter "until=72h"Pembersihan setelah setiap deploy, beserta trade-off-nya. Tanpa -a, image lama ber-tag SHA menumpuk sampai disk penuh; dengan -a saja, rilis sebelumnya ikut terhapus. Filter until=72h hanya menghapus image yang dibuat lebih dari 72 jam lalu, jadi rollback ke rilis yang baru lewat bisa dimulai dari salinan lokal. Nama service lain di server itu diganti placeholder.
Kesalahan yang benar-benar membuang waktu
Unhealthy, tetapi tetap live
Health check yang gagal hanya mengubah satu kata status di docker ps, tidak lebih. Container tetap melayani, dan restart policy tidak bereaksi pada status kesehatan. Pasangkan --wait dengan rollback yang sudah Anda latih, atau rilis yang rusak tetap hidup sampai ada yang sadar.
Yang akan saya ubah di sini: deploy tidak menunggu
Deploy situs ini menjalankan docker compose up -d --remove-orphans lalu lanjut, jadi rilis yang gagal health check tetap membuat workflow selesai hijau. Menambahkan --wait, dengan --wait-timeout sebagai batas atas, akan membuat run itu merah, dan itulah sinyal untuk rollback.
Deploy latest, lalu tidak punya versi untuk kembali
Jika server menjalankan apa pun yang ditunjuk latest, push yang buruk ikut menimpa jalan kembali Anda. Deploy tag SHA saja, seperti yang dilakukan .env situs ini, maka rilis sebelumnya selalu punya nama yang pasti.
Bersih-bersih yang berlebihan
docker image prune -a tanpa filter menghapus semua image yang tidak dipakai container, termasuk rilis yang mungkin Anda butuhkan malam ini, yang kemudian harus di-pull lagi dari registry, bisa jadi harus login dulu. Prune volume lebih parah: itu menghapus data. Filter image berdasarkan umur dan biarkan volume.
Hanya mengawasi dari dalam, atau membuka dashboard ke publik
Container bisa healthy sementara DNS, TLS, atau proxy di depannya rusak; hanya pengecekan dari luar yang melihatnya. Selain itu, perintah quick start Uptime Kuma, Prometheus, dan Grafana mem-publish port di semua interface. Bind ke 127.0.0.1 dan akses lewat SSH tunnel.
| Health check | Uptime check | Metrics | |
|---|---|---|---|
| Berjalan di mana | Di dalam container, dijalankan Docker | Dari luar, lewat jalur pengunjung | Di server, di-scrape secara terjadwal |
| Menjawab | Apakah prosesnya menjawab? | Apakah pengunjung bisa mengaksesnya? | Apakah kondisinya memburuk? |
| Menangkap | Aplikasi yang crash atau macet | Juga kegagalan DNS, TLS, proxy, dan jaringan | Tren pelan pada memori, CPU, dan disk |
| Terlewat | Semua yang ada di luar container | Penyebab kegagalannya | Tidak ada alert sampai Anda menambah alert rule |
| Tool di pelajaran ini | healthcheck di Compose | Uptime Kuma | Prometheus dan Grafana |
Lakukan di komputer Anda sendiri
Drill rollback. Anda butuh Docker dan folder lab dari pelajaran sebelumnya: server Node dengan route /health, Dockerfile multi-stage-nya, dan compose.yaml. Anda akan merilis versi rusak dengan sengaja, melihatnya tetap live, lalu me-rollback-nya.
Periksa compose.yaml: tag image diambil dari IMAGE, port hanya di-publish di loopback, dan health check memanggil /health setiap 5 detik.
services: web: image: ${IMAGE:-devops-lab:v1} restart: unless-stopped environment: APP_VERSION: ${APP_VERSION:-v1} ports: - "127.0.0.1:8080:3000" mem_limit: 128m cpus: "0.5" healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000/health"] interval: 5s timeout: 3s retries: 3 start_period: 5s logging: driver: json-file options: max-size: "1m" max-file: "3"Build v1, jalankan, dan tunggu sampai Docker melaporkannya healthy.
docker build -t devops-lab:v1 . docker compose up -d --wait curl http://127.0.0.1:8080/ # hello from v1Rilis sebuah bug: di src/server.ts, ubah cabang /health agar menjawab 500, bukan 200. Build sebagai v2 lalu deploy dengan --wait. Setelah sekitar 20 detik Compose melaporkan container unhealthy dan keluar dengan kode 1, tetapi curl tetap mendapat jawaban dari v2.
# src/server.ts, inside the /health branch res.writeHead(500, { "content-type": "text/plain" }); docker build -t devops-lab:v2 . IMAGE=devops-lab:v2 APP_VERSION=v2 docker compose up -d --wait; echo "exit=$?" curl http://127.0.0.1:8080/ # hello from v2: broken and live docker compose ps # STATUS ends in (unhealthy)Rollback dengan menjalankan tag sebelumnya. --wait keluar dengan kode 0 begitu v1 healthy, yang memakan waktu 8 detik saat diuji, dan log menyebut versi yang sedang berjalan.
IMAGE=devops-lab:v1 APP_VERSION=v1 docker compose up -d --wait; echo "exit=$?" curl http://127.0.0.1:8080/ # hello from v1 docker compose logs --tail 20 webOpsional, sudut pandang dari luar: tambahkan Uptime Kuma ke compose.yaml, hanya di-publish di loopback. Buka http://127.0.0.1:3001, selesaikan setup awal, lalu tambahkan monitor HTTP untuk http://web:3000/health. Ulangi langkah 3 dan 4, lalu lihat statusnya menjadi DOWN, kemudian UP. Uptime Kuma memeriksa dengan interval-nya sendiri, jadi bisa tertinggal dari --wait: itulah jawaban siapa yang tahu duluan.
# under services: uptime-kuma: image: louislam/uptime-kuma:2 restart: unless-stopped ports: - "127.0.0.1:3001:3001" volumes: - uptime-kuma:/app/data # at the end of the file, top level: volumes: uptime-kuma:Opsional, drill restore: hentikan Uptime Kuma, arsipkan volume-nya dengan container sekali pakai, restore arsip itu ke volume baru, lalu jalankan salinan kedua di atasnya di http://127.0.0.1:3002. Jika monitor Anda muncul di sana, backup-nya berfungsi.
docker compose stop uptime-kuma docker run --rm --volumes-from "$(docker compose ps -aq uptime-kuma)" -v "$PWD":/backup alpine tar czf /backup/kuma-backup.tgz -C /app/data . docker compose start uptime-kuma docker volume create kuma-restore docker run --rm -v kuma-restore:/data -v "$PWD":/backup alpine tar xzf /backup/kuma-backup.tgz -C /data docker run -d --name kuma-check -p 127.0.0.1:3002:3001 -v kuma-restore:/app/data louislam/uptime-kuma:2 # clean up afterwards docker rm -f kuma-check && docker volume rm kuma-restore
Tiga pertanyaan sebelum lanjut
Pilih jawaban untuk melihat kenapa benar atau salah. Tidak ada yang disimpan atau dinilai, jadi tebak saja dengan bebas.
Jawab dalam hati, lalu cek
1.v2 berhasil di-build, tetapi /health menjawab 500. Apa yang dilakukan docker compose up -d --wait?Lihat jawabannya
Jawaban:Perintah itu keluar dengan kode 1 dan melaporkan container unhealthy, tetapi v2 tetap melayani sampai Anda me-rollback. Dokumentasi Compose menjelaskan --wait sebagai menunggu service berjalan atau healthy; perintah itu tidak pernah membatalkan deploy.
2.Container Anda melaporkan healthy, tetapi pengunjung mendapat halaman error. Pengecekan mana yang menangkapnya?Lihat jawabannya
Jawaban:Uptime check dari luar. Health check berjalan di dalam container, jadi tidak bisa melihat DNS, TLS, atau reverse proxy di depannya.
3.Bagaimana cara tercepat mengembalikan rilis kemarin di situs ini?Lihat jawabannya
Jawaban:Ubah IMAGE di .env server ke tag SHA kemarin lalu jalankan docker compose up -d --wait. Pembersihan menyisakan image yang dibuat dalam 72 jam terakhir, jadi image itu masih ada di disk. Deploy berikutnya menulis ulang .env, jadi lanjutkan dengan git revert.
4.Apa yang perlu di-backup di server ini untuk portofolionya sendiri?Lihat jawabannya
Jawaban:Tidak ada yang unik. Kode ada di git, image ada di registry, konfigurasi ada di GitHub, dan volume cache bisa dibuat ulang. Backup volume milik service yang menyimpan data, misalnya riwayat monitoring, lalu uji restore-nya.
Bahasan mendalam terkait di situs ini
Sumber
Sumber primer yang diperiksa pada tanggal riset. Ikuti tautannya untuk versi terbaru.
- Dokumentasi Docker: docker compose up (--wait)
- Dokumentasi Docker: HEALTHCHECK
- Dokumentasi Docker: menjalankan container otomatis (restart policy)
- Dokumentasi Docker: docker image prune
- Dokumentasi Docker: volume (backup, restore, dan migrasi)
- Prometheus: gambaran umum
- Prometheus: memantau metrics container Docker dengan cAdvisor
- Prometheus: memantau metrics host Linux dengan Node Exporter
- Dokumentasi Grafana: menjalankan image Docker Grafana
- Uptime Kuma di GitHub
- Dokumentasi GitHub: menjalankan ulang workflow dan job