Sepanjang section ini kita mengoleksi alat demi alat — logs, inspect, stats, events, healthcheck — dan resep demi resep untuk keluarga kegagalan tertentu: container exit, jaringan putus, storage bengkak, build gagal, crash loop. Namun masalah dunia nyata jarang datang dengan label “ini masalah DNS” terpasang di dahinya; yang datang biasanya keluhan kabur semacam “toko online lemot” atau “ada error dari tadi malam”. Kerangka diagnostik yang baik mengubah keluhan kabur itu menjadi rangkaian keputusan yang bisa dieksekusi: fakta apa yang perlu dikumpulkan, hipotesis mana yang diuji lebih dulu, dan bagaimana membuktikan bahwa perbaikan benar-benar menuntaskan masalah. Chapter penutup ini merangkai lima langkah kerangka tersebut, mengujinya pada satu kasus lengkap dari laporan sampai pemulihan, lalu menutupnya dengan tiga prinsip pendukung dan satu diagram alur yang bisa kita bawa pulang ke insiden berikutnya.
Kerangka Lima Langkah #
Lima langkah berikut adalah distilasi dari seluruh resep section ini — setiap langkah mengubah bahan mentah menjadi bahan yang lebih tajam:
| Langkah | Transformasi (dari → ke) | Contoh dari section ini |
|---|---|---|
| 1. Presisikan gejala | keluhan kabur → gejala terukur | “ada error” → container api-kecil keluar kode 137 pukul 03:12 |
| 2. Kumpulkan fakta | dugaan → bukti dengan alat yang pas | rantai ps → inspect → logs pada laporan-harian |
| 3. Susun hipotesis | bukti → satu kalimat yang bisa gugur | “nama host di environment salah” |
| 4. Uji terisolasi | hipotesis → vonis | getent db-toko kosong; db menjawab 172.20.0.3 |
| 5. Perbaiki dan dokumentasikan | vonis → tindakan + catatan | .env DB_HOST=db + post-mortem empat baris |
Langkah 1 Presisikan Gejala #
Diagnosis dimulai jauh sebelum perintah pertama diketik — dimulai dari kalimat. Keluhan yang diterima hampir selalu kabur, dan pekerjaan pertama kita adalah menajamkannya:
| Keluhan kabur | Definisi presisi |
|---|---|
| “Ada error dari shift malam” | “Container api-kecil keluar kode 137 pukul 03:12; OOMKilled=true” |
| “Web mati” | “Proxy menjawab 502 pada /api/produk sejak 08:40; container backend berstatus Up” |
| “Toko lemot” | “Latensi endpoint /keranjang naik dari 120 ms ke 2,1 detik sejak deploy versi 1.4” |
Penajaman ini penting karena definisi presisi memotong ruang pencarian sekaligus menetapkan kriteria selesai. Kalimat “backend berstatus Up” pada baris kedua sudah menggugurkan seluruh teori “container mati” sebelum kita menghabiskan dua puluh menit ke arah yang salah; “sejak deploy versi 1.4” pada baris ketiga langsung menunjuk satu perubahan sebagai tersangka. Insiden dianggap tuntas hanya bila gejala versi tajamnya hilang — bukan bila kita sekadar merasa sudah cukup memeriksa.
Langkah 2 Kumpulkan Fakta dengan Alat yang Pas #
Dengan gejala yang tajam, kita mengumpulkan fakta menggunakan alat yang tepat untuk setiap pertanyaan — peta lengkapnya adalah hasil seluruh section ini:
| Pertanyaan | Alat |
|---|---|
| Container mana saja yang hidup, mati, atau restart? | docker ps / docker compose ps |
| Mengapa sebuah container berhenti — exit code, OOM, waktu? | docker inspect (struktur State) |
| Apa kata aplikasi sebelum bermasalah? | docker logs |
| Berapa CPU, memori, dan I/O yang dipakai? | docker stats |
| Kapan persisnya kejadian terjadi dan apa aksinya? | docker events |
| Apakah aplikasi dianggap sehat oleh healthcheck? | kolom STATUS dan State.Health |
Aturan mainnya satu: kumpulkan fakta secukupnya sebelum mengubah apa pun. Opini dini — “pasti cache-nya” atau “coba restart saja dulu” — adalah cara termahal menutup jalur diagnosis yang benar; fakta yang terkumpul rapi justru sering menunjukkan arahnya tanpa perlu ditebak.
Langkah 3 Susun Hipotesis yang Bisa Gugur #
Fakta yang terkumpul sebaiknya bermuara pada satu penjelasan paling mungkin, dan hipotesis tersebut harus dirumuskan agar bisa dibuktikan salah. Rumusnya sederhana: “bila hipotesis X benar, uji Y akan menghasilkan Z”. Pada skenario DNS di chapter Debugging Network, hipotesisnya adalah “nama host di environment salah” — dan ujinya, getent hosts db-toko yang kosong, dengan sendirinya menggugurkan semua hipotesis lain tentang firewall dan MTU. Hipotesis yang tidak bisa salah (“mungkin ada sesuatu yang aneh di jaringan”) bukan hipotesis, melainkan kegelisahan yang dibungkus kalimat.
Langkah 4 Uji secara Terisolasi #
Panggung pengujian sebaiknya sekecil mungkin, karena panggung kecil berarti siklus cepat dan kesimpulan bersih. Docker membuat isolasi ini murah: satu service dinyalakan sendiri dengan docker compose up -d db, aplikasi dicoba ulang lewat docker compose run --rm backend node src/repro.js, jaringan diselidiki dari container netshoot yang berbagi namespace dengan target, dan kegagalan build direproduksi manual di base image — tiga pola yang kita praktikkan berturut-turut sepanjang section ini. Semakin sedikit variabel yang ikut berdiri di panggung, semakin yakin kita bahwa hasil uji menunjuk hipotesis kita — bukan kebetulan dari komponen lain.
Langkah 5 Perbaiki dan Dokumentasikan #
Langkah terakhir yang paling sering dilewati adalah menuliskan hasil. Post-mortem yang baik tidak perlu panjang — empat baris sudah mencakup semuanya:
Apa : /api/produk menjawab 500 pada jam sibuk pagi 15 Oktober
Kenapa : connection pool backend berukuran 10 habis; permintaan mengantri sampai timeout
Deteksi : log backend penuh galat timeout; pg_stat_activity menunjukkan 10 koneksi dari backend
Cegah : ukuran pool dikonfigurasi lewat environment; alarm dipasang saat antrean pool menyentuh batasSatu Kasus dari Awal sampai Akhir #
Kasus penutup datang keesokan paginya, 15 Oktober, dan berjalan menempuh kelima langkah secara utuh. Laporan yang masih kabur: “halaman produk toko kadang lambat dan kadang gagal”. Langkah pertama menajamkannya lewat docker compose ps dan log: endpoint /api/produk menjawab 500 pada rentang 08:40–09:10, container backend berstatus Up, dan tidak ada satu pun restart di docker events — keluhan “mati” gugur sejak menit pertama. Langkah kedua mengumpulkan fakta: docker compose logs --since 1h backend dipenuhi baris Error: timeout exceeded when trying to connect, sementara docker stats menunjukkan CPU dan memori backend sepenuhnya normal, dan docker compose ps memastikan db sehat — resource dan ketersediaan database sama-sama bebas tuduhan.
Langkah ketiga merumuskan hipotesis tunggal: connection pool backend habis di jam sibuk — seluruh koneksi sibuk, permintaan baru mengantri sampai timeout, lalu menjawab 500. Rumusnya bisa gugur: bila benar, jumlah koneksi dari backend ke database harus menempel pada batas pool (10) selama galat terjadi. Langkah keempat mengujinya secara terisolasi — satu pertanyaan SQL ke db, tanpa menyentuh backend:
$ docker compose exec db psql -U toko -t -c "SELECT count(*) FROM pg_stat_activity WHERE usename = 'toko';"Output yang Dihasilkan:
10Angka tepat sepuluh — batas pool pg.Pool bawaan. Hipotesis terbukti, vonis turun. Langkah kelima memperbaiki dan mendokumentasikan: batas pool dinaikkan dari 10 ke 20 lewat konfigurasi (opsi max pada pg.Pool; di pustaka lain namanya max_size atau maximumPoolSize) yang kini dibaca dari environment, docker compose up -d backend menerapkan, verifikasi menunjukkan latensi kembali ke dua digit milidetik dan pg_stat_activity berkisar 15 pada jam sibuk, dan post-mortem empat baris tadi menutup insiden dengan pola pencegahan yang bisa dipakai tim.
Alur Lengkap dalam Satu Diagram #
Kelima langkah itu saling mengunci dalam satu alur — diagram berikut merangkumnya sebagai ingatan visual:
Baca diagram itu dari atas ke bawah dengan satu percabangan penting: bila pengujian justru menggugurkan hipotesis, alur kembali ke pengumpulan fakta — dengan pemahaman baru di tangan, bukan dengan keputusan asal mencoba. Kotak “verifikasi gejala benar-benar hilang” juga bukan formalitas: perbaikan yang belum diverifikasi masih tergolong hipotesis yang setengah diuji, dan insiden yang kambuh biasanya berakar pada langkah yang dianggap selesai padahal belum.
Tiga Prinsip Pendukung #
Ubah Satu Variabel pada Satu Waktu #
Saat menguji perbaikan, tahan godaan mengubah dua hal sekaligus. Naikkan mem_limit dan ganti image dalam satu percobaan, lalu container sembuh — kita tidak akan pernah tahu obat mana yang bekerja, dan salah satunya mungkin menyimpan efek samping. Ubah satu, ukur, lalu putuskan; itulah satu-satunya cara memberi atribusi yang jujur pada tiap perubahan.
Bagi Dua Ruang Masalah #
Bila ruang pencarian besar, jangan memeriksanya linear satu per satu — bagi dua. Segmentasi Dockerfile di chapter Mengatasi Build Gagal adalah bisect pada ruang instruksi; git bisect membagi dua rentang commit dengan uji reproduksi yang sama di tiap titik; daftar lima service yang dicurigai bisa dibagi menjadi “berjalan tanpa proxy” versus “berjalan lengkap”. Sepuluh langkah pemeriksaan linear runtuh menjadi tiga langkah bagi-dua — dan itulah sebabnya teknik ini menjadi tulang punggung banyak debugger.
Rubber Duck Debugging #
Prinsip terakhir tidak memerlukan server: cukup seekor bebek karet di meja — atau rekan setim yang bersedia mendengarkan. Menjelaskan masalah secara berurutan, dari gejala sampai hipotesis, memaksa kita mengurutkan fakta yang selama ini berhamburan di kepala; celah logika yang tak terlihat saat membaca sering terlihat saat diucapkan. Banyak insiden DNS di chapter Debugging Network tuntas di kalimat ketiga penjelasan: “aplikasi memanggil db-toko, padahal service-nya bernama…” — dan kalimat yang belum selesai itu sudah menjadi jawaban.
Lima langkah, tiga prinsip, dan satu diagram itulah bekal penutup section Observability dan Troubleshooting — perangkat kita kini lengkap dari perintah tunggal sampai kerangka berpikir. Namun hampir semua insiden yang kita bedah di section ini bermuara pada satu benang merah: container yang dibiarkan tanpa batas resource. Memory limit yang tak pernah dipasang berujung pada OOM, disk yang tak diukur berujung pada no space left, CPU yang tak dibagi berujung pada latensi yang memuncak — diagnosis yang baik sering berakhir di resource, dan mencegah selalu lebih murah daripada menyembuhkan. Section berikutnya mengambil alih tepat di titik itu: Manajemen Resource, dimulai dari chapter CPU Limit dan Reservation.
Referensi #
- Referensi CLI Docker — indeks seluruh perintah diagnosis yang dipakai kerangka lima langkah.
- Cheat Sheet Docker — ringkasan satu halaman perintah ps, logs, inspect, stats, dan events.
- Dokumentasi Docker Compose
—
compose run,compose exec, dancompose logssebagai alat uji terisolasi.