Misteri Container yang Terus Restart, Studi Kasus Troubleshooting Docker di Production

Kamandanu Wijaya 22 Januari 2026 ⏱️ 3 menit baca
Ilustrasi Insiden Docker Production dengan Notifikasi Error

Jam menunjukkan pukul 22:15 WIB ketika ponsel saya bergetar tanpa henti. Notifikasi dari sistem pemonitoran (monitoring) membanjiri layar “Critical Alert: Web Service is Down”. Sebagai seorang yang bertanggung jawab atas infrastruktur client, jantung saya berdegup kencang. Ini bukan sekadar gangguan kecil, ini adalah layanan utama yang digunakan oleh ribuan pengguna di malam hari. Dan kebetulan client saya ini sudah notice dan memberikan feedback langsung ke saya.

Di artikel ini, kita membahas Docker container crash secara praktis agar kamu paham konteks dan penerapannya.

Saya segera membuka laptop, menyeduh kopi instan seadanya, dan mulai masuk ke server melalui SSH. Pikiran saya kacau, mencoba menebak apa yang salah. Apakah ada serangan DDoS? Apakah database-nya corupt? Atau mungkin saya baru saja melakukan kesalahan saat deploy sore tadi?

Insiden ini mengajarkan saya bahwa di dunia Docker, status berwarna hijau (Running) tidak selalu berarti aplikasi kamu baik-baik saja. Seringkali, ada masalah yang tersembunyi di balik perintah docker ps.

Mari saya ajak kamu menyusuri langkah-langkah troubleshooting yang saya lakukan malam itu. Sebuah perjalanan dari kebingungan total hingga menemukan akar masalah yang ternyata merupakan kombinasi dari beberapa kelalaian kecil.

Gejala awal: alert yang tak berhenti

Laporan awal dari pengguna sangat jelas “Web-nya lemot banget, terus sering muncul Error 502 Bad Gateway”.

Langkah pertama yang saya lakukan adalah mengecek status container yang sedang berjalan. Dengan tangan sedikit gemetar, saya mengetikkan perintah sakti:

docker ps

Hasilnya membuat saya mengernyitkan dahi. Container web utama saya menunjukkan status Up 45 seconds (restarting)

Setiap kali saya merefresh perintah tersebut, angka “45 seconds” itu berubah kembali menjadi “2 seconds”, lalu “5 seconds”, lalu mati lagi. Ini yang disebut dengan Restart Loop. Container tersebut mencoba bangkit, gagal, mati, dan dipaksa hidup lagi oleh sistem restart Docker.

Visualisasi Restart Loop Docker

Investigasi tahap 1: membaca pesan kematian

Kesalahan pemula yang sering dilakukan adalah langsung melakukan restart server atau menghapus container. Jangan lakukan itu! Kamu butuh bukti. Bukti itu ada di log.

Saya mencoba melihat apa yang dikatakan oleh container yang sedang sekarat tersebut:

docker logs web_app_container

Lognya sangat singkat, biasanya hanya berisi:

[INFO] Starting application...
[ERROR] Could not connect to database at db_host:3306. Retrying...
[ERROR] Connection timeout. Exiting.

Oke, satu petunjuk ditemukan: aplikasi web mati karena tidak bisa mengobrol dengan database. Tapi tunggu, saya cek container database, statusnya Up 3 hours. Jadi, databasenya hidup. Kenapa aplikasinya bilang tidak bisa konek?

Investigasi tahap 2: menemukan sang biang kerok

Saya memeriksa lebih dalam menggunakan docker inspect. Ini adalah cara kita melihat “jeroan” dari sebuah container.

docker inspect web_app_container

Saya mencari bagian State. Dan di sana, saya menemukan pelaku utamanya:

"State": {
    "Status": "exited",
    "Running": false,
    "Paused": false,
    "Restarting": false,
    "OOMKilled": true,
    "Dead": false,
    "ExitCode": 137,
    "Error": "",
    "StartedAt": "2024-06-05T15:20:10Z",
    "FinishedAt": "2024-06-05T15:20:55Z"
}

OOMKilled: true. Artinya, sistem operasi secara paksa membunuh container saya karena dia menggunakan RAM melebihi batas yang diizinkan. Kode keluar (Exit Code) 137 adalah tanda khas dari Out Of Memory (OOM) killer.

Ternyata, sore tadi saya baru saja membatasi RAM container tersebut menjadi 512MB di file docker-compose.yml, tanpa menyadari bahwa saat aplikasi pertama kali ditarik (startup), dia butuh sekitar 600MB untuk melakukan pemindaian library dan inisialisasi cache.

Visualisasi Penggunaan Resource

Investigasi tahap 3: masalah belum selesai (disk full)

Setelah saya menaikkan batas RAM, container web mulai berjalan lebih lama. Namun, server secara keseluruhan tetap terasa sangat lambat. Perintah ls saja butuh waktu 3 detik untuk merespons.

Saya mengecek ruang penyimpanan disk:

df -h

Outputnya mengejutkan: Disk usage 99%. Ini aneh. Server ini punya disk 100GB dan data aplikasi saya tidak sampai 10GB. Di mana sisanya?

Saya menggunakan tool bawaan Docker untuk mengecek “sampah”:

docker system df

Ternyata, file log Docker sudah membengkak hingga puluhan Gigabyte. Container yang terus-menerus restart tadi menghasilkan ribuan baris log error, dan karena saya tidak mengatur batas ukuran log (log rotation), Docker terus menulis hingga memenuhi sisa disk yang ada.

Saat disk penuh, database tidak bisa menulis file temporer, sistem jadi lambat, dan akhirnya memicu efek domino yang meruntuhkan seluruh layanan.


Solusi akhir: memperbaiki arsitektur

Malam itu, saya tidak hanya menaikkan RAM. Saya memperbaiki seluruh konfigurasi agar kejadian memalukan ini tidak terulang lagi.

Berikut adalah perbandingan file docker-compose.yml saya yang bermasalah (Sore hari) dan yang sudah saya perbaiki (Tengah malam).

Sebelum perbaikan (banyak celah)

services:
  web:
    image: company/web-app:latest
    deploy:
      resources:
        limits:
          memory: 512M # Terlalu kecil untuk startup
    restart: always

  db:
    image: postgres:latest
    # Tidak ada pengecekan kesiapan database

Sesudah perbaikan (tangguh & terpantau)

services:
  web:
    image: company/web-app:latest
    deploy:
      resources:
        limits:
          memory: 1G # Dinaikkan untuk margin aman
        reservations:
          memory: 512M
    logging:
      driver: "json-file"
      options:
        max-size: "10m" # Batasi log agar tidak memenuhi disk
        max-file: "3"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    depends_on:
      db:
        condition: service_healthy # Tunggu DB benar-benar siap
    restart: unless-stopped

  db:
    image: postgres:latest
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Arsitektur Docker Compose yang Diperbaiki

Rekapitulasi akar masalah

Setelah matahari terbit dan sistem stabil, saya duduk sejenak untuk merenung. Insiden ini terjadi karena tiga hal kecil yang bertemu di waktu yang salah:

  1. Estimasi Memori yang Salah: Saya hanya melihat penggunaan RAM saat aplikasi idle, bukan saat startup.
  2. Masalah Urutan Startup: Web container mencoba langsung konek ke DB saat DB masih melakukan inisialisasi file. Tanpa mekanisme Wait-for-it atau Healthcheck, web container langsung crash.
  3. Logging yang Tak Terkendali: Tanpa rotasi log, insiden kecil bisa berubah menjadi kiamat disk space.

Pelajaran yang saya petik

Bagi kamu yang mengelola container di production, saya ingin menitipkan beberapa pesan hasil “berdarah-darah” di lapangan:

  1. Jangan Percaya Warna Hijau: Container status Up belum tentu aplikasinya jalan. Gunakan Healthcheck untuk memverifikasi fungsionalitas aplikasi di dalam container.
  2. Observabilitas adalah Kunci: Tanpa monitoring penggunaan resource (RAM, Disk, CPU), kamu bekerja dalam kegelapan. Minimal, pasang alert jika disk server mencapai 80%.
  3. Beri Ruang Napas (Margin): Jangan memberikan batas resource yang terlalu pas-pasan. Aplikasi butuh ruang ekstra untuk proses-proses tidak terduga di dalam runtime-nya (seperti Garbage Collection).
  4. Log Rotation adalah Wajib: Ini adalah hal pertama yang harus kamu setup di Docker daemon atau di setiap docker-compose file. Jangan biarkan file text menghancurkan layanan kamu.

Jika kamu masih baru dengan Docker dan merasa kewalahan dengan istilah-istilah di atas, saya sarankan untuk membaca panduan belajar Docker dari nol terlebih dahulu. Untuk mengamankan server production kamu secara keseluruhan, pelajari juga best practice server hardening Linux.

Penutup: masa depan deployment saya

Sejak insiden itu, saya mengubah standar deployment di tim saya. Kami selalu menyertakan healthcheck dan batasan log di setiap file konfigurasi. Kami juga menggunakan monitoring eksternal yang mengecek endpoint /health secara berkala.

Jika suatu hari nanti kamu mendapatkan alert di tengah malam seperti saya, bernapaslah sejenak. Jangan panik. Docker sudah memberimu semua alat yang dibutuhkan untuk mendiagnosis masalah. Kamu hanya perlu tahu di mana harus melihat.

Semoga cerita troubleshooting ini bermanfaat buat kamu dan bisa mencegah server kamu mengalami nasib yang sama. 🚀


Semoga pembahasan Docker container crash ini membantu kamu mengambil keputusan yang lebih tepat di lapangan.

Checklist Implementasi

  • Uji langkah di lab terlebih dulu sebelum produksi.
  • Dokumentasikan konfigurasi, versi, dan langkah rollback.
  • Aktifkan monitoring + alert untuk komponen yang diubah.
  • Audit akses dan terapkan prinsip least privilege.

Butuh Bantuan?

Jika ingin implementasi aman di produksi, saya bisa bantu assessment, eksekusi, dan hardening.

Hubungi Saya
Kamandanu Wijaya

Tentang Penulis

Kamandanu Wijaya

IT Infrastructure & Network Administrator

Administrator infrastruktur & jaringan dengan pengalaman enterprise 14+ tahun, fokus stabilitas, keamanan, dan automasi.

Sertifikasi: Google IT Support, Cisco Networking Academy, DevOps.

Lihat Profil

Butuh Solusi IT?

Tim DoWithSudo siap membantu setup server, VPS, dan sistem keamanan lo.

Hubungi Kami

Artikel Terkait

WhatsApp