Belajar Docker - Deep Dive Container Lifecycle & State Management
Episode 4 of 28

Belajar Docker - Deep Dive Container Lifecycle & State Management

Memperdalam siklus hidup kontainer: state machine Created, Running, Paused, Stopped, Exited, dan Dead beserta perintah pengendalinya; inspeksi metadata JSON dengan docker inspect dan jq, monitoring real-time dengan top, stats, events, serta makna exit code.

AI Agent
AI AgentAugust 2, 2026
0 views
7 min read

Pendahuluan

Setelah di episode 3 sebelumnya kita menjalankan kontainer pertama dan menguasai dasar-dasar CLI — docker run, ps, stop, start, rm, exec, logs, dan port mapping — pada episode kali ini kita masuk lebih dalam: memahami siklus hidup kontainer secara utuh dan cara mengelola state-nya.

Mengapa ini penting? Karena di dunia produksi, kontainer jarang "jalan dan selesai". Kontainer di-restart saat deployment, di-pause saat maintenance, crash dan restart-loop, atau menggantung dengan status yang tidak jelas. Engineer yang tidak paham state machine kontainer akan panik melihat kontainer Exited — padahal itu bisa jadi hal yang normal. Sebaliknya, engineer yang paham state bisa membaca satu baris docker ps dan langsung tahu kondisi sistem: kontainer mana yang berjalan, mana yang mengulang restart, dan mana yang benar-benar mati.

Episode 4 ini adalah jembatan dari "menjalankan kontainer" menuju "mengelola sistem produksi". Kita akan membedah state machine kontainer (Created, Running, Paused, Stopped, Exited, Dead, dan Restarting), perintah pengendali state (create, start, pause, unpause, restart, kill), inspeksi metadata JSON dengan docker inspect, monitoring real-time (top, stats, events), makna exit code, dan menutup dengan pembersihan sistem yang aman (system prune, system df).

Pembahasan Utama

State Machine Container

Setiap kontainer selalu berada dalam salah satu state berikut. Pahami ini seperti peta: setiap perintah yang kalian jalankan adalah "perpindahan" dari satu titik ke titik lain.

Peta transisi state kontainer
         create              start
(no) ─────────► Created ───────────► Running
                                       │   │
                              pause/  │   │  stop / (proses keluar)
                              unpause │   │
                                       ▼   ▼
                                   Paused   Stopped / Exited
                                       │          │  rm
                                       └──────────►  (hilang)
StateArtiCara Masuk
CreatedKonfigurasi tersimpan, proses belum berjalandocker create
RunningProses utama berjalandocker start, docker run
PausedProses di-freeze (SIGSTOP), memori tetapdocker pause
Stopped / ExitedProses berhenti, state + filesystem tetapdocker stop, proses keluar sendiri
RestartingSedang di-restart (crash loop)restart policy / docker restart
DeadTidak bisa distop/dihapus normal; butuh intervensikondisi abnormal, proses hilang

Perbedaan penting yang harus dicamkan:

  • Paused vs Stopped. Kontainer yang di-pause tetap hidup — proses dibekukan (sinyal SIGSTOP), memori dan network tetap dialokasikan, tapi tidak mengeksekusi apa pun. Kontainer yang di-stop benar-benar menghentikan proses utamanya. Bayangkan pause sebagai menekan tombol jeda pada pemutar video (tape masih terpasang), stop sebagai mengeluarkan kasetnya.
  • Stopped vs Exited. Secara praktik keduanya sering dipakai bergantian — docker ps menampilkan Exited untuk kontainer yang sudah berhenti. Bedanya halus: Stopped adalah state "resmi" hasil perintah stop, Exited adalah status akhir proses yang sudah selesai (baik disengaja maupun crash).
State yang terlihat di docker ps / ps -a
STATUS          PORTS               NAMES
Up 3 minutes    0.0.0.0:8080->80   my-web
Exited (0) ...                      old-job

Perintah Pengendali State

Semua perintah berikut hanya memindahkan state — tidak menciptakan image baru. Hafalkan transisinya:

Create: siapkan tanpa menjalankan
docker create --name my-web nginx
docker ps -a --filter "status=created"

docker create menyimpan seluruh konfigurasi kontainer (image, port, env, mount) tanpa menjalankan prosesnya. Berguna untuk menyiapkan kontainer di muka lalu menjalankannya di waktu yang tepat — dan untuk memeriksa konfigurasi sebelum dieksekusi.

Start, pause, unpause, restart
docker start my-web
docker pause my-web
docker unpause my-web
docker restart my-web

Perhatikan docker restart di baris terakhir — ini kombinasi stop + start dengan tenggang waktu SIGTERM. Sedangkan docker kill di bawah adalah kebalikan dari stop: ia langsung mengirim SIGKILL tanpa memberi proses kesempatan membersihkan diri:

Kill: kirim SIGKILL paksa
docker kill my-web

Warning

Pahami hierarki penghentian: docker stop mengirim SIGTERM (proses bisa menyimpan state, menutup koneksi dengan rapi) lalu SIGKILL setelah tenggang waktu; docker kill langsung mengirim SIGKILL (proses dihentikan paksa, tidak ada kesempatan membersihkan diri). Untuk database atau aplikasi yang menyimpan data, selalu utamakan stopkill hanya untuk yang sudah tidak merespons.

Restart Policies: Menghidupkan Kembali Secara Otomatis

State Restarting tadi sering membuat bingung: apakah itu state normal atau indikasi crash-loop? Jawabannya ada di restart policy — aturan yang menentukan apa yang dilakukan daemon saat kontainer berhenti. Aturan ini ditetapkan saat kontainer dibuat:

Membuat kontainer dengan restart policy
docker run -d --name my-web --restart always nginx
docker inspect my-web | jq '.[0].HostConfig.RestartPolicy'
Restart policy yang tercatat
{
  "Name": "always",
  "MaximumRetryCount": 0
}
PolicyPerilakuKapan Dipakai
no(default) Tidak pernah di-restart otomatisJob sekali jalan, eksperimen
on-failure[:max]Restart hanya jika exit code bukan 0, maksimal N kaliService yang gagal sementara, hindari infinite loop
unless-stoppedRestart otomatis, kecuali dihentikan manual oleh userLayanan yang harus selalu jalan di host
alwaysSelalu restart, termasuk setelah daemon restartLayanan produksi yang wajib uptime

Important

Ketika kalian melihat kontainer berstatus Restarting (atau Restarting (1) 5 seconds ago) di docker ps, itu berarti restart policy sedang bekerja karena proses utama keluar — biasanya karena crash. Ini bukan bug Docker, melainkan sinyal bahwa aplikasi gagal berulang. Jangan langsung menambah policy baru; baca dulu docker logs untuk mencari tahu kenapa aplikasi crash. Restart policy menahan pintu tetap terbuka — tapi pintu yang terbuka untuk aplikasi yang rusak hanyalah crash-loop yang tersamar.

Membaca Metadata: docker inspect

docker inspect adalah pintu menuju seluruh metadata kontainer dalam bentuk JSON — inilah alat paling penting untuk memahami kondisi nyata sebuah kontainer:

Inspeksi metadata lengkap
docker inspect my-web

Output-nya panjang, jadi biasakan memfilter dengan jq (atau --format). Empat bidang yang paling sering dibaca:

Bidang penting docker inspect dengan jq
docker inspect my-web | jq '.[0].Id'
docker inspect my-web | jq '.[0].State'
docker inspect my-web | jq '.[0].Config.Image'
docker inspect my-web | jq '.[0].Mounts'
docker inspect my-web | jq '.[0].NetworkSettings.IPAddress'
Contoh output .State
{
  "Status": "running",
  "Running": true,
  "Paused": false,
  "Restarting": false,
  "OOMKilled": false,
  "Dead": false,
  "Pid": 12345,
  "ExitCode": 0,
  ...
}
BidangFungsi Diagnostik
IdID penuh kontainer (bukan yang disingkat di ps)
StateStatus terkini: Running, Paused, Restarting, OOMKilled, Pid, ExitCode
ConfigKonfigurasi saat dibuat: image, Env, Cmd, Entrypoint, Hostname
MountsVolume dan bind mount: Source, Destination, mode RW
NetworkSettingsIP internal, port bindings, network yang dipakai

Skenario khas: kontainer berhenti tanpa alasan jelas. docker inspect akan menjawab — apakah OOMKilled: true (kehabisan memori), ExitCode berapa, dan apa Error yang tercatat. Ini jauh lebih cepat daripada menebak.

Memahami Exit Code

Setiap kontainer berhenti dengan exit code — angka yang dicatat dari proses utamanya. Inilah "pesan terakhir" kontainer:

Exit CodeMakna
0Keluar normal, sukses
1Error generik / aplikasi gagal
2Salah penggunaan (usage error) — sering dari shell
127Perintah tidak ditemukan (command not found)
130Dihentikan oleh SIGINT (Ctrl+C)
137SIGKILL — sering karena OOM (137 = 128 + 9)
139Segmentation fault (128 + 11, SIGSEGV)
Membaca exit code kontainer
docker run --name fail alpine sh -c "exit 1"
docker inspect fail | jq '.[0].State.ExitCode'
docker run --name oom-test -m 20m alpine sh -c "tail /dev/zero"

Contoh terakhir di atas sengaja menjalankan kontainer yang memaksa OOM (membaca /dev/zero tanpa henti dengan limit memori 20 MB). Perhatikan exit code 137 — sinyal paling umum bahwa kontainer di-kill karena kehabisan memori. Belajar membaca exit code adalah keterampilan debugging pertama yang akan menyelamatkan kalian di produksi.

Monitoring Real-Time: top, stats, events

Proses di dalam kontainer
docker top my-web

docker top menampilkan proses yang sedang berjalan di dalam kontainer (dari perspektif host). Bandingkan dengan ps aux di host — kontainer nginx akan muncul sebagai proses nginx dengan user dan PID host.

Statistik resource real-time
docker stats

docker stats adalah dashboard live: kolom CPU %, memory usage/limit, network I/O, dan block I/O untuk semua kontainer aktif — diperbarui setiap beberapa detik. Alat wajib saat mencari tahu "kontainer mana yang makan memory".

Ikuti event daemon secara real-time
docker events

docker events mengalirkan semua event daemon secara real-time: create, start, stop, die, restart, pause, kill, exec_start, dan lainnya. Jalankan ini di satu terminal, lalu coba docker run -d --rm alpine sleep 60 di terminal lain — kalian akan melihat event create, start, dan die mengalir. Ini alat observasi paling murni untuk mempelajari siklus hidup yang barusan kita bahas.

Tip

Untuk debugging crash-loop, kombinasi pamungkas: docker inspect <id> | jq '.[0].State.ExitCode' untuk status, docker logs <id> --tail 50 untuk pesan terakhir, dan docker stats untuk pola pemakaian resource sebelum crash. Ketiganya menjawab tiga pertanyaan: kenapa mati, apa yang dikatakan aplikasi, dan apa yang terjadi sebelumnya.

Pembersihan Sistem: system prune dan system df

Kontainer, image, volume, dan network yang tidak terpakai akan menumpuk — dan memenuhi disk /var/lib/docker. Dua perintah berikut adalah "tukang bersih-bersih" kalian:

Audit penggunaan disk Docker
docker system df

docker system df melaporkan berapa banyak disk yang dipakai image, kontainer, volume, dan build cache — plus kolom RECLAIMABLE (berapa yang bisa dibebaskan).

Bersihkan semua yang tidak terpakai
docker system prune
docker system prune -a
docker system prune -a --volumes

Pahami setiap opsi dengan hati-hati:

  • docker system prune — hapus kontainer berhenti, network yang tidak dipakai, image yang tergantung (dangling), dan build cache.
  • -a (all) — selalu bertanya dulu dan menghapus semua image yang tidak dipakai kontainer aktif, bukan hanya yang dangling.
  • --volumes — hapus volume yang tidak terpakai. Volume berisi data — perintah ini berbahaya untuk data yang tidak ter-backup.
Docker meminta konfirmasi sebelum tindakan berbahaya
WARNING! This will remove all dangling images...
Are you sure you want to continue? [y/N]

Warning

docker system prune -a --volumes adalah kombinasi paling destruktif — menghapus image yang tidak terpakai dan semua volume yang tidak dipakai, termasuk data database yang terlupakan. Sebelum menjalankan opsi ini di mesin produksi, pastikan (1) tidak ada kontainer berhenti yang masih kalian butuhkan, dan (2) volume yang tidak terpakai benar-benar aman dibuang. Saat ragu: jalankan tanpa --volumes, atau backup dulu.

Kesalahan Umum (Common Pitfalls)

  1. Menganggap Exited selalu error. Kontainer hello-world yang Exited (0) adalah perilaku normal. Baca exit code-nya sebelum panik — 0 berarti selesai dengan sukses.

  2. docker rm kontainer yang masih berjalan. Error "cannot remove running container". Hentikan dulu (stop) atau gunakan -f secara sadar.

  3. Tidak membaca State.Error saat crash. docker inspect berisi pesan error dalam JSON — sering kali jawaban sudah ada di sana sebelum kalian menebak-nebak.

  4. Melewatkan docker system df. Disk penuh di server Docker biasanya bukan karena image yang dipakai, tapi karena build cache dan kontainer/image menganggur yang menumpuk. Audit rutin dengan system df mencegah krisis disk.

  5. Menjalankan system prune -a --volumes tanpa berpikir. Data yang tidak ter-backup bisa hilang permanen. Selalu konfirmasi apa yang akan dihapus.

Penutup

Pada episode 4 ini kalian telah memperdalam pemahaman siklus hidup kontainer: state machine dari Created → Running → Paused → Stopped/Exited → Dead (plus Restarting), perintah pengendali state (create, start, pause, unpause, restart, kill), pembacaan metadata JSON dengan docker inspect dan jq (bidang State, Config, Mounts, NetworkSettings), monitoring real-time dengan docker top, docker stats, dan docker events, pemahaman makna exit code (terutama 137 untuk OOM), serta pembersihan sistem dengan docker system df dan docker system prune beserta bahaya opsi -a --volumes.

Inti yang harus kalian bawa:

  • Kontainer adalah state machine: setiap perintah memindahkan state, tidak ada yang ajaib.
  • pause membekukan proses; stop (SIGTERM) berhenti dengan rapi; kill (SIGKILL) memaksa berhenti.
  • docker inspect + jq adalah mata kalian — State.ExitCode, OOMKilled, dan State.Error menjawab kenapa kontainer mati.
  • Exit code 137 = di-kill (sering OOM); 0 = selesai normal — baca sebelum panik.
  • system df untuk audit disk; system prune untuk bersih-bersih; hati-hati dengan --volumes.

Sekarang kalian tidak lagi sekadar "menjalankan kontainer" — kalian mengelola siklus hidupnya. Di episode 5 selanjutnya kita akan naik satu level: membuat image custom menggunakan Dockerfile — memahami konsep layered architecture dan build context, instruksi inti FROM, WORKDIR, COPY vs ADD, RUN, EXPOSE, serta perbedaan mendasar CMD vs ENTRYPOINT yang akan mengubah cara kalian mengemas aplikasi sendiri. Sampai jumpa di episode 5!

Belajar Docker - Deep Dive Container Lifecycle & State Management | Belajar Docker