Implementasi Health Check dan Restart Policy di Docker Compose untuk Aplikasi Resilient

Lhuqita Fazry
Docker & DevOps docker docker-compose healthcheck container-resilience
Implementasi Health Check dan Restart Policy di Docker Compose untuk Aplikasi Resilient

Mengapa Container Terlihat Running Padahal Aplikasi Sudah Gagal

Status running pada docker ps hanya berarti proses utama container masih hidup. Status tersebut tidak menjamin aplikasi di dalamnya siap menerima trafik. Kesenjangan ini sering menimbulkan insiden di production. Load balancer mengirim request ke container yang sebenarnya sudah gagal memproses request.

Kami sering menemukan tiga skenario kegagalan yang tidak terdeteksi oleh status default. Pertama, aplikasi crash beberapa detik setelah start karena konfigurasi salah, tetapi orchestrator tidak menyadarinya. Kedua, aplikasi web sudah berjalan, tetapi database sebagai dependensi belum siap menerima koneksi. Request yang masuk pada jendela waktu ini pasti gagal. Ketiga, proses aplikasi mengalami deadlock atau kehabisan memori secara perlahan. Proses masih ada di tabel proses, tetapi tidak lagi responsif.

Masalah tersebut membutuhkan dua mekanisme yang saling melengkapi. Mekanisme pertama adalah healthcheck untuk mendeteksi kondisi aktual aplikasi secara berkala. Mekanisme kedua adalah restart policy untuk menentukan tindakan otomatis ketika container berhenti. Kombinasi kedua mekanisme tersebut membuat setup Docker Compose lebih resilient tanpa menambah kompleksitas operasional yang besar.

Memahami Cara Kerja Healthcheck di Docker Compose

Fitur healthcheck menjalankan perintah uji di dalam container pada interval tertentu. Docker mencatat hasilnya sebagai status kesehatan yang terpisah dari status container. Tiga status yang tersedia adalah starting, healthy, dan unhealthy. Status starting berlaku selama periode start_period. Status berubah menjadi healthy setelah uji berhasil. Status berubah menjadi unhealthy setelah gagal sebanyak retries kali berturut-turut.

Konfigurasi healthcheck terdiri dari lima parameter utama. Parameter test mendefinisikan perintah uji yang dijalankan. Parameter interval mengatur jeda antar pengujian, default 30 detik. Parameter timeout mengatur batas waktu setiap pengujian, default 30 detik. Parameter retries mengatur jumlah kegagalan beruntun sebelum status menjadi unhealthy, default 3 kali. Parameter start_period memberikan masa tenggang saat aplikasi melakukan inisialisasi, default 0 detik.

Bentuk test memiliki tiga varian. Varian CMD menjalankan perintah langsung tanpa shell. Varian CMD-SHELL menjalankan perintah melalui shell sehingga mendukung operator seperti && dan ||. Varian NONE menonaktifkan healthcheck yang diwarisi dari base image. Kami merekomendasikan CMD-SHELL untuk uji HTTP sederhana dan CMD untuk uji biner seperti pg_isready.

Siklus status healthcheck container dari starting hingga healthy

Gambar: Ilustrasi infrastruktur server dan container yang menjalani pemeriksaan kesehatan berkala — Sumber: Unsplash

yaml
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost/ || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s

Konfigurasi di atas menguji kesiapan nginx setiap 10 detik. Workflow pengujian dimulai setelah masa tenggang 20 detik agar proses nginx sempat melakukan inisialisasi. Perintah wget memeriksa apakah server merespons request HTTP pada port 80. Hasil pengujian dapat kami lihat melalui kolom status pada output docker ps. Status yang diharapkan adalah Up (healthy) setelah beberapa siklus pengujian berhasil.

Mengonfigurasi Healthcheck untuk Web dan Database dalam Satu Compose File

Aplikasi nyata jarang berdiri sendiri. Pola umum adalah service web yang bergantung pada postgres atau redis. Tanpa pengaturan yang tepat, service web akan start lebih dulu dan langsung gagal karena database belum siap. Kondisi ini memicu restart berulang yang sebenarnya tidak perlu terjadi.

Deep Learning Bootcamp
Machine Learning • Intermediate

Deep Learning Bootcamp

A beginner-friendly, highly interactive bootcamp designed to take you from found...

Register

Solusi yang tepat adalah mendefinisikan healthcheck pada setiap service dan mengatur depends_on dengan kondisi service_healthy. Konfigurasi tersebut memastikan Compose menunggu hingga dependensi benar-benar sehat sebelum menjalankan service yang bergantung. Pendekatan ini jauh lebih andal daripada sekadar mengandalkan urutan start atau jeda waktu statis.

yaml
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost/ || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 15s

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: secret123
      POSTGRES_DB: appdb
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

volumes:
  db-data:

Workflow pada file tersebut berjalan dalam urutan yang terkontrol. Service db dijalankan terlebih dahulu dan menjalani masa inisialisasi sekitar 30 detik. Perintah pg_isready memverifikasi apakah postgres sudah menerima koneksi. Service web baru dijalankan setelah status db menjadi healthy. Pola ini menghilangkan race condition saat startup dan mengurangi log error koneksi yang membingungkan.

Verifikasi dapat kami lakukan dengan dua perintah standar. Perintah pertama menampilkan ringkasan status semua service dalam satu tampilan.

bash
docker compose ps

docker inspect --format='{{json .State.Health.Status}}' $(docker compose ps -q web)

Output yang diharapkan dari perintah pertama menunjukkan healthy pada kedua service. Output dari perintah kedua menampilkan string healthy dalam format JSON. Informasi detail seperti log kegagalan terakhir tersedia melalui docker inspect pada bagian Health.Log. Data tersebut sangat membantu saat proses debugging konfigurasi uji yang terlalu ketat atau terlalu longgar.

Memilih Restart Policy yang Tepat untuk Setiap Skenario Kegagalan

Parameter restart mengatur perilaku Compose ketika container berhenti atau ketika daemon Docker melakukan restart. Empat nilai yang tersedia adalah no, always, unless-stopped, dan on-failure. Setiap nilai dirancang untuk kebutuhan operasional yang berbeda.

Nilai no berarti container tidak pernah direstart otomatis. Nilai tersebut cocok untuk job sekali jalan atau environment pengujian manual. Nilai always selalu merestart container dalam kondisi apa pun, termasuk setelah host melakukan reboot. Nilai unless-stopped memiliki perilaku mirip always, tetapi menghormati keputusan manual ketika kami menghentikan container secara eksplisit. Nilai on-failure hanya merestart ketika container keluar dengan kode error bukan nol. Varian on-failure:5 membatasi jumlah percobaan hingga lima kali untuk mencegah loop tanpa akhir.

Poin penting yang sering disalahpahami adalah status unhealthy tidak memicu restart otomatis. Mekanisme restart policy hanya bereaksi terhadap berhentinya container, bukan terhadap status kesehatan. Keterbatasan ini berarti kombinasi healthcheck dan restart tetap membutuhkan pemantauan eksternal atau mekanisme orkestrasi tambahan untuk skenario production yang kompleks.

Strategi restart otomatis untuk menjaga ketersediaan service container

Gambar: Visualisasi sistem teknologi yang membutuhkan strategi pemulihan otomatis agar tetap tersedia — Sumber: Unsplash

yaml
services:
  api:
    image: nginx:alpine
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost/ || exit 1"]
      interval: 15s
      timeout: 5s
      retries: 3
      start_period: 20s

  worker:
    image: alpine:3.19
    command: ["sh", "-c", "echo processing job && sleep 5 && exit 1"]
    restart: "on-failure:5"

Konfigurasi di atas menerapkan strategi yang berbeda untuk dua peran yang berbeda. Service api menggunakan unless-stopped karena service tersebut bersifat long-running dan harus tetap tersedia setelah reboot. Service worker menggunakan on-failure:5 karena kegagalan sesekali masih wajar untuk dicoba ulang, tetapi kegagalan berulang menandakan masalah yang membutuhkan intervensi manual.

Rekomendasi praktis untuk tim kami adalah sebagai berikut. Service API stateless sebaiknya memakai unless-stopped. Service worker dengan pekerjaan idempotent sebaiknya memakai on-failure dengan batas percobaan. Service database sebaiknya memakai unless-stopped dengan volume persistent. Environment development lokal sebaiknya memakai unless-stopped agar tidak perlu menjalankan perintah start berulang kali setiap hari.

Memverifikasi Ketahanan Aplikasi dengan Simulasi Kegagalan

Konfigurasi yang belum diuji sama dengan asumsi. Kami perlu membuktikan bahwa setup benar-benar pulih saat terjadi kegagalan nyata. Simulasi sederhana dapat dilakukan tanpa tool tambahan, cukup dengan perintah Docker standar.

Langkah pertama adalah menjalankan seluruh stack dalam mode detached dan memastikan semua service mencapai status healthy. Langkah kedua adalah mensimulasikan kegagalan dengan menghentikan proses utama di dalam container atau menghentikan service database sementara. Langkah ketiga adalah mengamati bagaimana status kesehatan berubah dan apakah service yang terdampak pulih tanpa intervensi manual.

bash
docker compose up -d

docker compose ps

docker compose kill web

docker compose ps

docker compose logs --tail=50 web

docker compose up -d web

docker inspect --format='{{json .State.Health}}' $(docker compose ps -q web)

Rangkaian perintah di atas mendemonstrasikan siklus penuh pengujian ketahanan. Perintah kill mensimulasikan crash mendadak pada service web. Perintah ps setelah crash menunjukkan perubahan status container. Perintah logs membantu kami memahami urutan kejadian dari sisi aplikasi. Perintah up memulihkan service yang gagal. Perintah inspect terakhir mengonfirmasi bahwa status kesehatan kembali menjadi healthy.

Checklist untuk production mencakup tiga hal yang sering terlewat. Pertama, tetapkan start_period yang cukup panjang untuk aplikasi dengan waktu startup lambat seperti Java atau aplikasi yang menjalankan migrasi database. Nilai yang terlalu kecil menyebabkan status unhealthy palsu saat aplikasi sebenarnya masih melakukan inisialisasi. Kedua, gunakan timeout yang realistis untuk uji yang bergantung pada jaringan. Ketiga, siapkan pemantauan di luar Compose karena Docker Compose tidak mengirim notifikasi saat status berubah menjadi unhealthy. Integrasi dengan Prometheus atau layanan alerting sederhana menutup celah observabilitas tersebut.

Ingin memperdalam keterampilan deployment dan orkestrasi container untuk kebutuhan production? Kami menyediakan program bootcamp DevOps di Rumah Coding yang membahas Docker, Compose, dan pipeline deployment secara sistematis dari dasar hingga praktik langsung.

Course Terkait

GreenGuard: Intelligent Plant Disease Diagnosis Web App
Premium Course Machine Learning

Deep Learning Bootcamp

A beginner-friendly, highly interactive bootcamp designed to take you from foundational concepts to deploying real-world Artificial Intelligence applications. Through a completely project-based approach, you will master the core of Deep Learning, Artificial Neural Networks, and Computer Vision using Python and TensorFlow, ultimately building a professional-grade AI web application for your portfolio.

Capstone Project

GreenGuard: Intelligent Plant Disease Diagnosis Web App

  • Interactive Image Upload UI: A clean, user-friendly interface built with Streamlit that supports drag-and-drop image uploads directly from a computer or mobile phone.
  • Real-Time AI Inference: Utilizes a lightweight, optimized CNN model (like MobileNetV2) to process the image and return a diagnosis in seconds without heavy server load.
  • Confidence Scoring Dashboard: Visually displays the model's prediction probability (e.g., "95% confident this is Tomato Late Blight") using interactive progress bars or charts.
7 Weeks Intermediate
View Course Details
Domain-Specific AI Knowledge Assistant
Premium Course Machine Learning

LLM Bootcamp

This project-based bootcamp is designed for beginners to dive practically into the world of Large Language Models (LLMs). Through hands-on building, you will learn how to interact with top-tier AI APIs, master prompt engineering, orchestrate complex workflows using LangChain, and implement Retrieval-Augmented Generation (RAG) to query your own documents. By the end of this course, you will have the skills to build, test, and deploy a fully functional, custom AI web application.

Capstone Project

Domain-Specific AI Knowledge Assistant

  • Dynamic Document Processing: A sidebar interface allowing users to upload new PDF or TXT files, which the app automatically chunks, embeds, and stores in the vector database.
  • Context-Aware Chat UI: A modern chat interface built with Streamlit that maintains conversation history, allowing users to ask follow-up questions naturally.
  • Strict Guardrails (Anti-Hallucination): System instructions designed so the AI politely declines to answer questions that fall outside the context of the uploaded documents.
7 Weeks Beginner
View Course Details
End-to-End Student Success Predictor
Premium Course Machine Learning

Machine Learning Bootcamp

A beginner-friendly, 7-week project-based bootcamp designed to take you from Python basics to deploying your first Machine Learning model. Through hands-on practice, you will master essential data manipulation, build predictive algorithms, and develop an end-to-end, industry-ready application to kickstart your career in data science.

Capstone Project

End-to-End Student Success Predictor

  • Automated Data Pipeline: A preprocessing script that automatically cleans missing values, encodes categorical data (like course type or student background), and scales numerical inputs.
  • Predictive Engine: A tuned machine learning classification model (e.g., Random Forest) specifically optimized for high Recall, ensuring that "at-risk" students are not missed.
  • Interactive Web Dashboard: A user-friendly Streamlit interface featuring a sidebar where instructors can manually input a student's study hours, quiz scores, and login frequency to get an instant pass/fail probability.
7 Weeks Intermediate
View Course Details

Related Articles