Satu per satu knob konfigurasi telah kita pasang sepanjang section ini — perintah, environment, identitas, port, direktori kerja, kebijakan bangkit, batas resource, hingga tata kelola sinyal PID 1 — dan di setiap chapter kita berpapasan dengan kejadian-kejadian yang sama: container lahir, berjalan, kadang dibekukan, lalu berhenti atau dihapus. Chapter penutup section ini menarik mundur kamera sampai seluruh kejadian itu muat dalam satu bingkai: peta lengkap state yang bisa dihuni sebuah container, perintah mana yang memindahkannya dari satu state ke state lain, dan bagaimana membaca posinya dari luar lewat docker ps dan docker inspect. Mesin kita bersih dari container setelah chapter sebelumnya, jadi kita akan menghuni peta itu satu per satu dengan satu penumpang bernama siklus — dari diciptakan sampai tidak lagi bisa ditemukan.
Peta Lima State Container #
Sebuah container hidup dalam tepat lima keadaan besar. Diagram berikut memetakan kelimanya beserta perintah yang menjadi jalan transisinya:
Mari kita telaah tiap jalan pada peta di atas:
[*]menujuCreatedlewatdocker create— penciptaan menyiapkan segalanya kecuali kehidupan: writable layer disiapkan, konfigurasi tersimpan, nama terdaftar, tetapi PID 1 belum pernah lahir.CreatedmenujuRunninglewatdocker start— proses utama dinyalakan; inilah momen namespace, cgroups, dan jaringan benar-benar dihuni oleh proses.RunningdanPausedbolak-balik lewatpausedanunpause— pembekukan memakai freezer cgroup, sehingga proses tetap hidup di memori tanpa mendapat setitik waktu CPU.RunningmenujuExitedlewatstopataukill— dua jalur yang sudah kita bandingkan tuntas pada Chapter *Menghentikan dan Menjalankan Container: sopan denganSIGTERMlalu masa tenggang, atau seketika denganSIGKILL`.ExitedmenujuRunninglewatdocker start— kebangkitan manual; bila kebangkitannya diserahkan kepada daemon, kita sudah tahu pilihan kebijakannya dari Chapter Restart Policy.- Tiga pintu menuju
Removed— container yang dibangun saja maupun yang sudah berhenti dihapus lewatdocker rm; container yang masih berjalan harus dihapus paksa lewatdocker rm -f. Removedmenuju[*]tanpa jalan pulang — penghapusan bersifat final: nama, konfigurasi, dan writable layer lenyap bersamaannya.
Membangun Tanpa Menjalankan #
Perintah docker create adalah bagian dari docker run yang selama ini bekerja diam-diam. docker run sebenarnya menjalankan dua langkah berurutan — menciptakan container, lalu langsung menyalakannya — dan pemisahan itu sempat kita janjikan sejak Chapter Menjalankan Container Pertama. Kini kita jalankan paruh pertamanya sendiri:
$ docker create --name siklus nginxOutput yang Dihasilkan:
468fa01723fb92a2e080be487d8df9a66aabf72b83993c9170fb5edc7c93bc05$ docker ps -aOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
468fa01723fb nginx "/docker-entrypoint.…" 3 seconds ago Created siklus$ docker inspect --format '{{.State.Status}}' siklusOutput yang Dihasilkan:
createdMari kita telaah keadaan yang belum hidup itu:
- Output
docker createadalah ID penuh — 64 karakter heksadesimal, sama persis bentuk yang dicetakdocker runmode detached; penciptaan memang langkah yang sama. STATUSmembacaCreated, bukanUp— container terdaftar didocker ps -anamun tidak pernah didocker ps, karena PID 1-nya belum pernah dinyalakan..State.Statusberbunyicreated— state ini punya nama resmi di metadata, salah satu dari lima penghuni peta kita.- Kegunaannya nyata untuk persiapan — kita bisa menciptakan container beserta seluruh flag konfigurasinya lebih dulu — port, environment, batas resource — lalu menyalakannya belakangan pada momen yang kita pilih; beberapa pola deployment dan tool CI memang memakai pemisahan ini.
Menyusuri Siklus Hidup #
Sekarang kita jalani sisanya selangkah demi selangkah, memotret docker ps pada tiap perhentian. Perhentian pertama — kehidupan:
$ docker start siklusOutput yang Dihasilkan:
siklus$ docker psOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
468fa01723fb nginx "/docker-entrypoint.…" 48 seconds ago Up 4 seconds siklus$ docker inspect --format '{{.State.Status}} {{.State.StartedAt}}' siklusOutput yang Dihasilkan:
running 2026-10-13T10:07:22.418392067ZPerhentian kedua — pembekuan:
$ docker pause siklusOutput yang Dihasilkan:
siklus$ docker psOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
468fa01723fb nginx "/docker-entrypoint.…" 2 minutes ago Up 26 seconds (Paused) siklusPerhentian ketiga — pencairan:
$ docker unpause siklusOutput yang Dihasilkan:
siklus$ docker psOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
468fa01723fb nginx "/docker-entrypoint.…" 2 minutes ago Up 34 seconds siklusMari kita telaah tiga perhentian pertama itu:
Createdtidak pernah berubah menjadiUptanpadocker start— kolomCREATEDtetap mengingat usia container sejak diciptakan, sementaraSTATUSberganti menjadiUp 4 secondsbegitu PID 1 menyala..State.StartedAtmencatat jam dinyalakannya — waktu ISO dengan presisi nanodetik;docker restartkelak menimpanya dengan waktu yang baru, karena prosesnya memang generasi baru.(Paused)menempel pada status hidup — container yang dibekukan tetap dihitung hidup dengan umur yang terus berjalan; freezer hanya mencabut waktu CPU, bukan nyawa — persis perilaku yang kita praktikkan denganwebpada Chapter Menghentikan dan Menjalankan Container.unpausemelanjutkan persis dari titik beku — status kembali menjadiUpbiasa tanpa jejak; bagi nginx di dalamnya, seolah tidak ada yang terjadi.
Perhentian keempat adalah jalan buntu yang justru paling mengajar. Mari kita coba memotong jalan — menghapus container yang masih hidup:
$ docker rm siklusOutput yang Dihasilkan:
Error response from daemon: You cannot remove a running container 468fa01723fb92a2e080be487d8df9a66aabf72b83993c9170fb5edc7c93bc05. Stop the container before attempting removal or force removeGalat yang akrab ini — kita jumpai pertama kali pada Chapter Menghapus Container — menawarkan dua jalan keluar yang jujur. Jalan pertama adalah sopan: hentikan dulu, baru hapus. Container yang sedang dibekukan pun ditolak dengan cara serupa — cairkan dulu, baru urus penghentiannya. Jalan kedua adalah docker rm -f: mengirim SIGKILL tanpa masa tenggang lalu menghapus sisanya dalam satu tarikan napas. Kita ambil jalan pertama:
$ docker stop siklusOutput yang Dihasilkan:
siklus$ docker ps -aOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
468fa01723fb nginx "/docker-entrypoint.…" 3 minutes ago Exited (0) 7 seconds ago siklus$ docker inspect --format '{{.State.Status}} {{.State.ExitCode}}' siklusOutput yang Dihasilkan:
exited 0Perhentian terakhir — penghapusan:
$ docker rm siklusOutput yang Dihasilkan:
siklus$ docker ps -aOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESMari kita telaah dua perhentian terakhir itu:
Exited (0) 7 seconds ago— nginx menutup dirinya dengan rapi lewat sinyal berhenti bawaan imagenya, dandocker stopselesai jauh sebelum masa tenggang; kode0di dalam kurung adalah exit code PID 1 yang juga terbaca sebagai.State.ExitCode.docker rmkali ini diterima — penghentian lebih dulu membuat penghapusan sah; urutan stop lalu rm persis ritual yang diajarkan galat ini sejak Section Dasar Docker CLI.- Tabel
docker ps -amenampilkan kepala kolom saja —siklustidak lagi terdaftar di mana pun; nama dan ID-nya telah dibebaskan, dan container berpindah ke stateRemovedyang tidak punya jejak di daftar.
Enam Wajah STATUS di docker ps #
Kolom STATUS sepanjang perjalanan kita tadi menampilkan empat wajah — dan sepanjang section ini kita berpapasan dengan dua wajah lain. Tabel berikut merangkum keenamnya beserta state resminya:
| STATUS di docker ps | State di inspect | Artinya |
|---|---|---|
Created | created | container sudah dibangun, PID 1 belum pernah dinyalakan |
Up 2 minutes | running | proses berjalan dengan sehat |
Up 2 minutes (Paused) | paused | proses hidup namun dibekukan freezer cgroup |
Exited (0) | exited | berhenti rapi — PID 1 keluar dengan kode sukses |
Exited (137) | exited | tumbang oleh SIGKILL — docker kill, masa tenggang habis, atau OOM killer |
Restarting (1) | restarting | menunggu jeda ulang kebijakan restart dengan exit code terakhir di kurung |
Dua baris terakhir membawa kabar dari chapter-chapter tetangga. Exited (137) adalah warisan lapar yang kita serahkan kepada OOM killer pada Chapter CPU dan Memory Limit — dan docker inspect --format '{{.State.OOMKilled}}' adalah pembeda antara OOM dan docker kill biasa, sebagaimana kita praktikkan di sana. Restarting (1) adalah status sesaat yang kita tangkap pada Chapter Restart Policy — keadaan menunggu jeda backoff di antara dua percobaan kebangkitan, dengan angka kegagalan tercatat di dalam kurungnya.
Membaca State Lewat docker inspect #
Empat field .State berikut adalah panel indikator yang paling sering kita baca sepanjang section ini, dan kini maknanya lengkap:
| Field | Contoh nilai | Artinya |
|---|---|---|
.State.Status | created, running, paused, restarting, exited | posisi container pada peta lima state saat dibaca |
.State.ExitCode | 0 sampai 255 | kode keluar terakhir PID 1, termasuk konvensi 128 + sinyal |
.State.StartedAt | 2026-10-13T10:07:22.418392067Z | waktu PID 1 terakhir kali dinyalakan |
.State.OOMKilled | true atau false | apakah kematian terakhir adalah karya OOM killer |
Flag --rm menutup daftar perintah transisi dari sisi lain: menghadiahkan container penghapusan otomatis begitu keluar dari state running, tanpa kita menyebut docker rm — materi yang kita praktikkan pada Chapter Menghapus Container. Bersama docker rm -f dan seluruh perintah pada peta kita, kebutuhan sehari-hari sudah terjelaskan semua: mulai dari container sekali pakai yang menghapus dirinya sendiri, container yang disiapkan matang untuk disimpan, sampai container yang dibangkitkan tanpa henti oleh kebijakannya.
Peta yang barusan kita susuri juga menyimpan satu fakta yang sengaja kita simpan untuk penutup section ini: docker rm tidak hanya menghapus nama dan konfigurasi. Seluruh tulisan yang dibuat proses di dalam container — berkas log yang ditulis nginx, berkas yang diunduh, basis data kecil yang tumbuh — hidup di writable layer, dan layer itu lenyap bersama container-nya pada perhentian terakhir. Exited masih menyimpan semuanya; Removed tidak menyimpan apa-apa. Maka pertanyaan section berikutnya menanti dengan sendirinya: bagaimana caranya membuat data hidup lebih lama dari container yang menampungnya? Section Penyimpanan Data menjawabnya dari fondasinya — dimulai dari Chapter Writable Container Layer, tempat kita membongkar lapisan yang barusan kita lihat lenyap itu.
Referensi #
- docker container create
— membuat container dalam keadaan
Createdtanpa menjalankannya. - docker container pause — pembekuan proses lewat freezer cgroup beserta pencairannya.
- docker container stop
— urutan
SIGTERMdanSIGKILLbeserta masa tenggangnya. - docker container inspect
— field
.State.Status,.State.ExitCode,.State.StartedAt, dan.State.OOMKilled.