Melihat memang bukan mengendalikan — dan pertanyaan yang kita tinggalkan di akhir Chapter Melihat Container kini menanti jawaban: bagaimana caranya memadamkan web untuk menghemat resource tanpa membuang container-nya, lalu menyalakannya kembali dalam kondisi yang sama? Sebuah server sungguhan tidak menyala selamanya; ada jendela pemeliharaan, ada penghematan di akhir pekan, ada pula momen darurat ketika sebuah layanan harus dimatikan seketika. Docker menyediakan satu keluarga perintah untuk seluruh keadaan itu — stop, start, restart, kill, dan pause — dan masing-masing bekerja dengan mekanisme yang berbeda di balik layar. Chapter ini membedah kelima perintah tersebut beserta sinyal-sinyal Linux yang menjadi bahasa komunikasi di antaranya, sehingga kita selalu bisa memilih cara mematikan yang tepat untuk situasi yang tepat.
Menghentikan Container dengan docker stop #
Perintah docker stop adalah cara paling sopan untuk mematikan container yang sedang berjalan. Kata “sopan” bukan basa-basi: docker stop memberi kesempatan kepada aplikasi di dalam container untuk beres-beres — menutup koneksi, mem flush penulisan, dan menghentikan dirinya sendiri — sebelum Docker mengambil tindakan paksa. Mari kita matikan web yang sejak Chapter Melihat Container masih setia melayani permintaan HTTP:
$ docker stop webOutput yang Dihasilkan:
webMari kita telaah perintah dan output di atas:
- Output satu baris
web—docker stopmencetak kembali identifier yang kita sebut sebagai tanda keberhasilan; baik nama maupun ID pendek sama-sama diterima, dan outputnya pun mengikuti bentuk yang kita pakai. - Bentuk modernnya — sesuai tabel alias pada Chapter Struktur Perintah Docker, perintah ini setara dengan
docker container stop; dokumentasi resmi memakai bentuk modern, sementara kedua bentuk menghasilkan efek yang identik. webtidak terhapus — container hanya berhenti; seluruh konfigurasi, nama, ID, dan isinya tetap berada di tangan daemon, siap dinyalakan ulang kapan pun.
Kita buktikan klaim terakhir itu dengan jendela yang sudah kita kenal:
$ docker ps -aOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7c2a91b3e55 nginx "/docker-entrypoint.…" 13 minutes ago Exited (0) 5 seconds ago web
3a1c8f2e9b7d redis:7 "docker-entrypoint.s…" 7 minutes ago Up 7 minutes 6379/tcp cache
d4e5f6a7b8c9 hello-world "/hello" 15 minutes ago Exited (0) 15 minutes ago quirky_einsteinMari kita telaah tiga baris pada tabel di atas:
Exited (0) 5 seconds agomilikweb— status berhenti lengkap dengan kode keluar0di dalam kurung; kode0berarti proses utama menyelesaikan pematian dengan rapi, dan makna lengkap angka-angka semacam ini kita bedah tuntas pada Chapter Memahami Exit Code.cachedanquirky_einsteintidak tersentuh —docker stophanya membidik container yang kita sebutkan; Redis milikcachetetap berjalan, danquirky_einsteintetap tergeletak dalam keadaan berhenti seperti sejak Chapter Menjalankan Container Pertama.- Kolom
PORTSmilikwebkosong — bukan karena pemetaan8080->80hilang;docker psmemang tidak menampilkan pemetaan port untuk container yang sedang berhenti. Pemetaan tersebut tetap tercatat pada konfigurasi container dan akan aktif kembali begitu container dinyalakan.
Lalu apa yang sebenarnya terjadi di balik layar? docker stop mengirim sinyal SIGTERM kepada PID 1 — proses utama container, dalam kasus kita skrip entrypoint nginx — lalu menunggu dengan masa tenggang 10 detik secara default. Bila proses berhasil berhenti sebelum masa tenggang habis, container berhenti dengan anggun. Bila proses justru ngotot tetap hidup, Docker mengirim SIGKILL yang memaksa proses mati tanpa proses penawaran. Diagram berikut memetakan alurnya:
Mari kita telaah setiap tahap pada diagram di atas:
- Titik masuk —
docker stoptidak membunuh apa pun secara langsung; langkah pertamanya selalu mengirim sinyal sopan dan menunggu. - Titik keputusan — masa tenggang default 10 detik adalah batas atas, bukan durasi tunggu wajib; container yang merespons cepat akan berhenti jauh sebelum batas itu.
- Jalur atas — proses yang menghormati sinyal berhenti dengan sendirinya, dan status akhirnya mencerminkan penutupan yang rapi.
- Jalur bawah — sinyal
SIGKILLtidak bisa ditangkap atau diabaikan oleh proses apa pun; container yang menempuh jalur ini berhenti dalam keadaan dipaksa, dan statusnya berubah menjadiExited (137)— angka yang artinya kita bongkar nanti.
Menyalakan Kembali dengan docker start #
Container yang berhenti adalah container yang menunggu — dan docker start adalah tombolnya. Perintah ini menghidupkan kembali container yang sudah ada, bukan membuat container baru; bedanya dengan docker run persis seperti bedanya menyalakan kembali komputer lama versus membeli komputer baru. Inilah pemisahan tahap create dan start yang kita janjikan pada Chapter Menjalankan Container Pertama: docker create menyiapkan container tanpa menjalankannya, docker start menghidupkannya, dan docker run hanyalah keduanya digabung:
$ docker start webOutput yang Dihasilkan:
web$ docker psOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7c2a91b3e55 nginx "/docker-entrypoint.…" 15 minutes ago Up 5 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp web
3a1c8f2e9b7d redis:7 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 6379/tcp cacheMari kita telaah apa yang barusan terjadi pada kedua output di atas:
docker startmengembalikan identifier yang kita sebut — sama sepertidocker stop, output satu baris ini adalah konfirmasi; bila kita memanggil dengan ID pendekf7c2a91b3e55, outputnya pun ID pendek tersebut.- Kolom
CREATEDtetap15 minutes ago— waktu pembuatan container tidak pernah berubah oleh stop dan start; yang berubah hanyalahSTATUS, yang kini menunjukkanUp 5 secondskarena proses PID 1 baru saja dinyalakan ulang. - Kolom
PORTSterisi penuh kembali — pemetaan0.0.0.0:8080->80/tcpbeserta pasangan IPv6-nya menempel pada container, bukan pada sesi terminal; tidak adadocker runbaru, tidak ada flag-pyang diketik ulang. curl localhost:8080kini menjawab — halamanWelcome to nginx!yang sama persis melayani permintaan berikutnya, karena seluruh konfigurasi dan isi writable layer web tidak tersentuh oleh siklus stop-start ini.
Mengatur Masa Tenggang dengan –time #
Masa tenggang 10 detik cukup untuk hampir semua aplikasi, tetapi tidak untuk semuanya. Aplikasi dengan banyak koneksi berumur panjang, antrian pesan yang harus dikuras, atau basis data yang sedang menulis checkpoint bisa membutuhkan waktu berhenti yang jauh lebih lama. Flag -t atau bentuk panjangnya --time mengubah masa tenggang untuk satu pemanggilan — nilainya dalam detik:
$ docker stop -t 30 webOutput yang Dihasilkan:
webMari kita telaah perintah di atas:
-t 30sebelum nama container — kita memberi nginx ruang bernapas sampai 30 detik sebelumSIGKILLdiizinkan turun; nilainya menggantikan angka 10 default hanya untuk pemanggilan ini.- Perintah tetap kembali hampir seketika — nginx menutup dirinya dalam hitungan milidetik karena menangani sinyal berhenti dengan rapi; masa tenggang hanyalah batas atas, bukan durasi tunggu yang harus habis.
- Kapan angka besar benar-benar dibutuhkan — bayangkan aplikasi yang harus menyelesaikan transaksi setengah jalan sebelum keluar; bila lognya menunjukkan proses berhenti selalu terpotong oleh
SIGKILL, angka default-lah yang patut dicurigai.
Kita hidupkan kembali web supaya mesin kita kembali seperti semula untuk latihan-latihan berikutnya:
$ docker start webOutput yang Dihasilkan:
webMenyalakan Ulang dengan docker restart #
Kadang yang kita butuhkan bukan berhenti lalu menyalakan dengan dua perintah, melainkan satu perintah yang melakukan keduanya berurutan. docker restart menghentikan container dengan jalur sopan yang sama seperti docker stop — termasuk masa tenggang yang bisa diatur dengan -t — lalu langsung menyalakannya kembali. Pola ini akrab pada dunia server: mengubah berkas konfigurasi lalu memuat ulang layanannya:
$ docker restart webOutput yang Dihasilkan:
webUntuk membuktikan bahwa proses di dalamnya benar-benar baru, kita manfaatkan kebiasaan --format yang kita pelajari pada Chapter Melihat Container:
$ docker ps --format "{{.Names}}: {{.Status}}"Output yang Dihasilkan:
web: Up 5 seconds
cache: Up 13 minutesMari kita telaah kedua baris di atas:
web: Up 5 seconds— proses PID 1 di dalamwebbaru berumur beberapa detik;docker restartmematikan proses lama dan melahirkan proses baru, bukan sekadar menyegarkan sesuatu di dalam container.cache: Up 13 minutes— container lain tidak ikut tersentuh, dan umurnya terus berjalan; restart selalu bersifat per container, sesuai identifier yang kita sebutkan.- Container yang sama, bukan container baru — ID, nama, pemetaan port, dan writable layer tetap milik
webyang lama; hanya prosesnya yang berganti generasi.
Menghentikan Paksa dengan docker kill #
Semua jalur di atas berbagi satu asumsi: proses di dalam container bersedia berhenti. docker kill membuang asumsi itu — perintah ini mengirim SIGKILL secara langsung, tanpa sinyal peringatan dan tanpa masa tenggang. Proses yang menerima SIGKILL mati seketika di tangan kernel; tidak ada penangan sinyal yang bisa mencegahnya:
$ docker kill webOutput yang Dihasilkan:
web$ docker ps -aOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7c2a91b3e55 nginx "/docker-entrypoint.…" 21 minutes ago Exited (137) 5 seconds ago web
3a1c8f2e9b7d redis:7 "docker-entrypoint.s…" 15 minutes ago Up 15 minutes 6379/tcp cache
d4e5f6a7b8c9 hello-world "/hello" 23 minutes ago Exited (0) 23 minutes ago quirky_einsteinMari kita telaah perbedaan yang paling penting pada tabel di atas:
Exited (137)pada barisweb— bandingkan denganExited (0)pada sesidocker stopsebelumnya; angka137adalah128 + 9, yaitu konvensi kernel untuk “proses dihentikan oleh sinyal nomor 9 aliasSIGKILL” — pembahasan lengkapnya menanti di Chapter Memahami Exit Code.- Dua bekas luka yang berbeda pada satu mesin —
webkini tercatat berhenti paksa, sementaraquirky_einsteintercatat berhenti rapi; satu kolomSTATUSsaja sudah cukup untuk membaca sejarah kematian dua container ini. webtetap tidak terhapus —docker killmematikan proses, bukan membuang container; ia tetap bisa dinyalakan ulang seperti biasa.docker killjuga menerima flag--signal— bila kita ingin mengirim sinyal lain sepertiSIGHUPatauSIGUSR1kepada PID 1, flag inilah alatnya; tanpa flag tersebut,SIGKILLadalah pilihan bawaan.
web tidak menyimpan data penting apa pun — halaman statis bawaan nginx — sehingga membangkitkannya kembali dari kematian paksa tidak menyisakan masalah:
$ docker start webOutput yang Dihasilkan:
webMembekukan Container dengan docker pause #
Ada satu keadaan yang belum tercakup keluarga perintah di atas: kita ingin container diam sebentar — bukan mati, hanya berhenti bergerak. docker pause melakukan hal itu dengan mekanisme yang sepenuhnya berbeda dari sinyal: kernel Linux membekukan seluruh proses dalam container lewat freezer cgroup, seperti menekan tombol pause pada pemutar musik. Proses tetap hidup di memori, semua statusnya terjaga, hanya saja tidak mendapat waktu CPU sama sekali:
$ docker pause webOutput yang Dihasilkan:
web$ docker psOutput yang Dihasilkan:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7c2a91b3e55 nginx "/docker-entrypoint.…" 23 minutes ago Up 2 minutes (Paused) 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp web
3a1c8f2e9b7d redis:7 "docker-entrypoint.s…" 17 minutes ago Up 17 minutes 6379/tcp cacheMari kita telaah status barunya:
Up 2 minutes (Paused)— container tetap berstatus hidup, lengkap dengan durasinya, dan kata(Paused)menempel sebagai penanda keadaan beku; bandingkan dengankillyang mengubah status menjadiExited.- Pemetaan port tetap terpasang — karena prosesnya masih hidup, kolom
PORTStidak dikosongkan; tetangga di jaringan tetap bisa mengirim paket, hanya tidak ada yang menjawab.
Dan di sinilah muncul gejala yang tidak terlupakan: coba jalankan curl localhost:8080 sekarang. Koneksi TCP berhasil dibuka — handshake dijawab oleh jaringan kernel — tetapi permintaan HTTP kita tidak pernah mendapat balasan, karena nginx di dalam container sedang beku dan tidak membaca apa pun. Terminal tampak menggantung di tengah; tekan Ctrl-C untuk melepaskannya. Kita cairkan kembali container-nya:
$ docker unpause webOutput yang Dihasilkan:
webProses di dalam web melanjutkan eksekusi persis dari titik pembekuan, dan curl localhost:8080 kembali menjawab halaman selamat datang seperti biasa. Tidak ada proses yang mati, tidak ada yang dimulai ulang — hanya jeda yang tidak dirasakan siapa pun di dalam container.
Memilih antara stop, kill, dan pause #
Lima perintah pada chapter ini terasa serupa di permukaan — semuanya “mengurus container yang sedang hidup” — tetapi bekerja pada mekanisme yang sama sekali berbeda. Tabel berikut merangkum lima aspek yang membedakan ketiga jalur utamanya:
| Aspek | docker stop | docker kill | docker pause |
|---|---|---|---|
| Sinyal yang dikirim | SIGTERM atau sinyal STOPSIGNAL image, lalu SIGKILL bila perlu | SIGKILL langsung | Tidak ada sinyal — freezer cgroup |
| Masa tenggang | 10 detik default, dapat diubah dengan -t | Tidak ada | Tidak relevan |
| Nasib proses | Berhenti total | Berhenti total | Tetap hidup namun dibekukan |
| Status di docker ps | Exited dengan kode aplikasi, umumnya Exited (0) | Exited (137) | Up … (Paused) |
| Kapan dipakai | Mematikan container secara sopan sehari-hari | Keadaan darurat atau container yang macet | Membekukan beban untuk pemeriksaan |
Aturan praktisnya sederhana: docker stop adalah pilihan bawaan untuk segala pematian yang tidak mendesak, docker kill adalah pemecah kebuntuan ketika sopan santun sudah tidak mempan, dan docker pause adalah tombol jeda yang tidak membunuh siapa pun. Kini kita mahir mengendalikan hidup-mati container, tetapi satu masalah pelan-pelan menumpuk di sudut mesin: setiap siklus stop yang kita jalankan hari ini meninggalkan container berhenti yang terus tercatat di docker ps -a, dan quirky_einstein sudah lama menjadi penghuninya. Chapter berikutnya, Menghapus Container, membereskan jejak-jejak itu dengan docker rm, flag --rm, dan docker container prune — sekaligus membahas apa yang sebenarnya ikut terbuang saat sebuah container dihapus.
Referensi #
- docker container stop
— referensi resmi stop beserta flag
--timedan perilaku masa tenggang. - docker container kill
— referensi resmi kill beserta flag
--signal. - docker container pause — referensi resmi pause dan unpause berbasis freezer cgroup.