Struktur project yang rapi menekan jumlah kecelakaan, tetapi tidak pernah meniadakannya: daemon tetap bisa mati setelah jam kerja, container tetap bisa berhenti tanpa pamit, dan disk tetap bisa penuh diam-diam oleh image lama. Kabar baiknya, hampir semua kecelakaan Docker mengelompok ke dalam sepuluh pola yang sama, dan masing-masing punya urutan diagnosis pendek yang bisa dijalankan dalam satu menit. Chapter ini menyajikan kesepuluh pola itu sebagai resep siap pakai: gejala ditulis persis seperti yang terlihat di terminal, langkah disusun sebagai daftar singkat yang bisa discan, dan setiap resep ditutup rujukan ke chapter tempat masalahnya dibedah tuntas. Jadikan halaman ini halaman pertama yang dibuka saat pager berbunyi.

Sepuluh Resep Cepat #

Setiap resep mengikuti pola yang sama: kenali gejala dari pesannya, jalankan langkah berurut dari yang paling murah, lalu hentikan begitu penyebabnya ketemu. Semua perintah ditulis inline supaya cepat disalin satu per satu.

Daemon Mati #

Gejala: setiap perintah Docker dijawab Cannot connect to the Docker daemon. Is the docker daemon running on this host?

  1. Periksa status layanan: systemctl status docker.
  2. Baca 50 baris log terakhir daemon: journalctl -u docker -n 50.
  3. Perbaiki akar masalahnya — paling sering kesalahan sintaks pada daemon.json yang baru saja diedit.
  4. Nyalakan ulang layanan dengan sudo systemctl restart docker, lalu verifikasi lewat docker info.

Diagnosis lengkap dengan keluaran aslinya dibedah di chapter Troubleshooting Instalasi.

Permission Denied pada Socket #

Gejala: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock padahal perintah dijalankan tanpa sudo.

  1. Tambahkan pengguna ke grup docker: sudo usermod -aG docker $USER.
  2. Keluar dan masuk kembali agar keanggotaan grup aktif — logout total, bukan sekadar membuka tab terminal baru.
  3. Uji tanpa sudo: docker ps.
  4. Bila tetap gagal, periksa izin socket dengan ls -l /var/run/docker.sock dan cocokkan grupnya.

Rantai izin socket ini diurai tuntas di chapter Mengatur Akses Docker.

Container Berhenti dengan Misterius #

Gejala: container berhenti beberapa detik setelah start, dan docker ps -a menampilkan status Exited (137) atau Exited (1) tanpa pesan galat di layar.

  1. Baca log sebelum mati: docker logs --tail 50 <nama>.
  2. Bedah waktunya dan penanda OOM: docker inspect --format '{{.State.ExitCode}} {{.State.OOMKilled}}' <nama>.
  3. Ingat kamus exit code: 137 berarti SIGKILL termasuk OOM kill, 143 SIGTERM, 127 perintah tidak ditemukan.
  4. Bila OOMKilled bernilai true, naikkan --memory atau perbaiki kebocoran memori aplikasi.

Ritual otopsi lengkapnya dibedah di chapter Membaca Container Exit.

Port Bentrok #

Gejala: docker run gagal dengan Bind for 0.0.0.0:8080 failed: port is already allocated.

  1. Cari penghuni port host: docker ps --filter publish=8080.
  2. Hentikan container lama yang memegangnya: docker stop <nama>.
  3. Bila bukan container, periksa proses host dengan ss -tlnp | grep 8080.
  4. Atau ganti port host di sisi kiri pemetaan: -p 8081:80.

Mekanisme publish dua sisi ini dijelaskan di chapter Port Mapping.

Rate Limit saat Pull #

Gejala: docker pull dijawab Error response from daemon: You have reached your pull rate limit. ... (429).

  1. Login dengan Docker ID gratis: docker login — kuota anonim 100 pull per 6 jam naik menjadi 200.
  2. Tunda pull yang tidak mendesak beberapa jam sampai jendela kuota berganti.
  3. Untuk tim, pertimbangkan registry mirror internal agar image populer hanya ditarik sekali.
  4. Pin image penting lewat digest supaya pull ulang hanya terjadi saat benar-benar diperlukan.

Aturan kuota dan strukturnya diurai di chapter Docker Hub.

Build Mendadak Lambat #

Gejala: rebuild menyentuh langkah npm ci dari nol padahal hanya satu baris kode yang berubah.

  1. Periksa urutan COPY di Dockerfile — kode sumber wajib berada di bawah manifest dependensi.
  2. Pastikan manifest (package.json, go.mod) tidak ikut berubah pada commit terakhir.
  3. Periksa .dockerignore: context yang membesar mengubah cache key COPY . ..
  4. Amati baris mana yang kehilangan CACHED pada keluaran build untuk menemukan instruksi penyebabnya.

Mekanisme cache key-nya dibedah sampai ke akarnya di chapter Build Cache.

Disk Penuh #

Gejala: pull, build, atau run gagal dengan no space left on device.

  1. Ukur dulu pemakainya: docker system df dan perhatikan kolom RECLAIMABLE.
  2. Bersihkan container berhenti dan image dangling: docker system prune.
  3. Tambahkan -a --volumes bila memang ingin bersih total — hati-hati, volume bernama ikut terhapus.
  4. Bersihkan cache BuildKit yang biasanya paling gemuk: docker builder prune.
  5. Setelah pulih, aktifkan rotasi log di daemon.json agar kejadian tidak berulang.

Keluarga masalah disk dan mount dibedah di chapter Debugging Storage.

DNS Antar Container Gagal #

Gejala: container saling tidak bisa terhubung lewat nama — ping db tidak pernah menjawab.

  1. Cek jaringan kedua container: docker inspect --format '{{json .NetworkSettings.Networks}}' <nama>.
  2. Bila keduanya berada di bridge, pindahkan ke user-defined network: docker network create net-app lalu docker run --network net-app.
  3. Uji resolusi dari dalam container: docker exec <nama> nslookup db.
  4. Ingat: DNS embedded 127.0.0.11 hanya aktif pada user-defined network, bukan default bridge.

Kap mesin DNS internal ini dibongkar di chapter Container DNS.

Volume Permission Denied #

Gejala: aplikasi tiba-tiba tidak bisa menulis ke volume — Permission denied muncul tepat setelah ganti image.

  1. Bandingkan UID aplikasi lama dan baru — angka pemilik di kernel tidak pernah berganti nama: docker exec <nama> id.
  2. Periksa pemilik sebenarnya di host: ls -ln $(docker volume inspect --format '{{.Mountpoint}}' <volume>).
  3. Samakan UID lewat useradd -u di Dockerfile, atau chown sekali dari container sementara root.
  4. Bila image tidak bisa diubah, tulis user: "1000:1000" pada service compose.

Lima pola solusi lengkapnya dibandingkan di chapter Permission dan Ownership Volume.

Compose Reconnect Loop #

Gejala: setelah docker compose up -d, service web terus restart dengan galat koneksi database meski db tampak menyala.

  1. Pastikan aplikasi menghubungi db lewat nama service, bukan localhost — di dalam container, localhost adalah container itu sendiri.
  2. Periksa status healthcheck db: docker compose ps harus menampilkan (healthy).
  3. Tambahkan kondisi kesiapan pada web: depends_on: { db: { condition: service_healthy } }.
  4. Bila database memang butuh waktu lama, perpanjang retries dan interval healthcheck daripada memperjarang restart policy.

Batas urutan start versus jaminan kesiapan diurai di chapter depends_on dan Startup Order.

Sepuluh resep ini menuntaskan kecelakaan operasional, tetapi kelas masalah berikutnya lebih sunyi: celah keamanan tidak mengirim pesan galat ke terminal dan tidak membuat container restart — ia duduk diam sampai ditemukan orang lain. Satu-satunya pertahanan yang bekerja adalah audit berkala lewat checklist yang setiap butirnya bisa dieksekusi. Chapter berikutnya menyediakan checklist keamanan dua puluh sembilan butir dalam Checklist Keamanan, lengkap dengan contoh docker run hardened sebagai patokan akhirnya.

Referensi #