Lewati ke isi

Server & Infrastruktur

Healthcheck Docker, Cara Container Tahu Dirinya Sehat

Healthcheck membuat Docker tahu apakah aplikasi di dalam container benar-benar melayani, bukan sekadar prosesnya hidup. Begini cara menulis dan membacanya.

Terbit 5 menit baca

Jawaban singkat

Healthcheck adalah perintah kecil yang dijalankan Docker berkala di dalam container. Bila perintah itu gagal beberapa kali berturut-turut, status container berubah menjadi unhealthy, sehingga kamu, Compose, atau alat pemantau bisa bereaksi sebelum pengguna mengeluh.

Daftar isi
  1. Proses hidup belum tentu aplikasi sehat
  2. Menulis healthcheck di Dockerfile
  3. Healthcheck di Docker Compose
  4. Membaca status kesehatan container
  5. Apakah Docker otomatis me-restart container yang unhealthy?
  6. Rancang endpoint kesehatan yang jujur

Bayangkan container aplikasi web yang statusnya Up 3 days di docker ps, tapi setiap request ke situsmu berakhir dengan error 502. Prosesnya memang masih hidup, hanya saja aplikasinya macet, kehabisan koneksi database, atau terjebak di loop. Dari sudut pandang Docker, semuanya baik-baik saja.

Healthcheck menutup celah itu. Kamu memberi Docker satu perintah untuk menguji apakah aplikasi benar-benar melayani, misalnya memanggil endpoint /health. Docker menjalankannya berkala, lalu menandai container sebagai healthy atau unhealthy. Status inilah yang bisa dipakai untuk urutan start di Compose, pemantauan, dan keputusan restart.

Proses hidup belum tentu aplikasi sehat

Tanpa healthcheck, satu-satunya yang Docker ketahui adalah apakah proses utama (PID 1 di dalam container) masih berjalan. Kalau proses itu keluar, Docker tahu dan bisa menjalankan ulang sesuai restart policy. Tapi banyak kegagalan tidak membuat proses keluar: thread pool penuh, deadlock, koneksi ke database putus dan tidak pulih, atau disk penuh sehingga aplikasi menolak menulis.

Healthcheck menjawab pertanyaan yang lebih berguna, yaitu "apakah layanan ini bisa dipakai sekarang?". Perintahnya dijalankan di dalam container, jadi ia melihat aplikasi dari dekat, tanpa terpengaruh firewall atau reverse proxy di luar.

Aturannya sederhana. Perintah yang keluar dengan kode 0 berarti sehat, kode 1 berarti tidak sehat. Kode 2 dicadangkan oleh Docker dan sebaiknya tidak dipakai.

Healthcheck bisa ditanam langsung di image lewat instruksi HEALTHCHECK. Contoh untuk aplikasi web yang mendengarkan port 8080:

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
  CMD curl -fsS http://localhost:8080/health || exit 1

Opsi -f pada curl membuat respons HTTP 4xx dan 5xx dianggap gagal, sedangkan || exit 1 memastikan kode keluarnya selalu 1 saat gagal. Setiap image hanya boleh punya satu HEALTHCHECK. Kalau ada lebih dari satu, yang terakhir yang berlaku. Image turunan bisa mematikan healthcheck warisan dengan HEALTHCHECK NONE.

Satu hal yang sering terlupa: image ramping (berbasis Alpine, distroless, atau slim) sering tidak membawa curl. Pilihannya memasang curl atau wget saat build, memakai perintah bawaan aplikasi (misalnya pg_isready di image PostgreSQL atau redis-cli ping di image Redis), atau menulis skrip pengecek kecil dalam bahasa yang memang sudah ada di image.

Berikut arti setiap opsi beserta nilai bawaannya menurut dokumentasi Docker:

OpsiFungsiBawaan
--intervalJeda antar pengecekan30 detik
--timeoutBatas waktu satu pengecekan, lewat dari ini dianggap gagal30 detik
--start-periodMasa pemanasan, kegagalan di masa ini tidak dihitung0 detik
--start-intervalJeda pengecekan selama masa pemanasan (Docker Engine 25 ke atas)5 detik
--retriesJumlah gagal berturut-turut sebelum dinyatakan unhealthy3

Dengan nilai bawaan, container baru dinyatakan unhealthy setelah tiga kali gagal berturut-turut, jadi butuh sekitar satu setengah menit. Untuk layanan yang penting, interval lebih pendek dengan timeout yang realistis biasanya lebih pas.

Healthcheck di Docker Compose

Kalau image dibuat orang lain dan kamu tidak ingin mengubah Dockerfile, healthcheck bisa ditulis di compose.yaml. Nilai di sini menimpa healthcheck yang tertanam di image.

services:
  db:
    image: postgres:17
    environment:
      POSTGRES_PASSWORD: rahasia
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  app:
    image: contoh/app:latest
    depends_on:
      db:
        condition: service_healthy

Bagian depends_on dengan condition: service_healthy adalah manfaat terbesar healthcheck di Compose. Tanpa itu, Compose hanya menunggu container database dibuat, bukan menunggu PostgreSQL siap menerima koneksi. Hasilnya aplikasi sering gagal saat start pertama karena database belum siap. Dengan healthcheck, app baru dijalankan setelah db berstatus healthy.

Bentuk CMD menjalankan perintah langsung tanpa shell, sedangkan CMD-SHELL menjalankannya lewat /bin/sh -c sehingga operator seperti || dan variabel lingkungan bisa dipakai.

Membaca status kesehatan container

Status kesehatan tampil di kolom STATUS pada docker ps, misalnya Up 2 minutes (healthy). Ada tiga kemungkinan: starting selama masa pemanasan, healthy, dan unhealthy.

Untuk melihat riwayat pengecekan lengkap dengan keluaran perintahnya:

docker inspect --format '{{json .State.Health}}' nama-container

Hasilnya berisi status, jumlah kegagalan berturut-turut, dan beberapa log pengecekan terakhir. Bagian log ini sangat membantu saat healthcheck gagal karena hal sepele, misalnya port salah atau curl tidak ada di image.

Apakah Docker otomatis me-restart container yang unhealthy?

Di Docker Engine biasa (tanpa Swarm), jawabannya tidak. Status unhealthy hanya sebuah label. restart: always atau unless-stopped hanya bereaksi saat proses utama keluar, bukan saat healthcheck gagal. Di mode Swarm, task yang unhealthy akan diganti oleh orkestrator.

Jadi di VPS tunggal, kamu perlu sesuatu yang membaca status itu. Pilihannya antara lain alat pemantau yang memberi notifikasi, skrip kecil yang dijalankan berkala untuk me-restart container berstatus unhealthy, atau membuat aplikasi keluar sendiri saat mendeteksi kondisi rusak sehingga restart policy yang bekerja. Kalau kamu sudah memakai Uptime Kuma, endpoint kesehatan yang sama juga bisa dipantau dari luar.

Rancang endpoint kesehatan yang jujur

Healthcheck hanya sebaik perintah yang diuji. Endpoint /health yang selalu menjawab "OK" tanpa memeriksa apa pun tidak memberi informasi. Sebaliknya, endpoint yang memeriksa terlalu banyak hal (misalnya API pihak ketiga) bisa membuat container dianggap sakit padahal masalahnya di luar kendalimu.

Patokan yang masuk akal: periksa hal yang memang dibutuhkan aplikasi untuk melayani, seperti koneksi database dan kemampuan menulis ke disk, dengan query yang ringan. Jaga agar pengecekan selesai jauh di bawah nilai timeout, karena healthcheck yang lambat ikut membebani server. Hindari juga perintah yang meninggalkan file sementara atau koneksi menggantung di setiap putaran.

Healthcheck cocok dipadukan dengan praktik lain di kesalahan umum Docker di produksi dan pembatasan CPU serta RAM container, supaya satu container yang bermasalah tidak menyeret seluruh server.

Intinya, healthcheck mengubah "prosesnya masih jalan" menjadi "layanannya bisa dipakai". Tulis di Dockerfile atau Compose, pakai service_healthy untuk urutan start, lalu pastikan ada yang benar-benar membaca status unhealthy, karena Docker biasa tidak akan bertindak sendiri.

Sumber & referensi

Baca juga