Bab ini menutup Section Docker Image dengan satu pertanyaan yang setiap pemakai Docker akhirnya harus jawab: berapa besar sesungguhnya wilayah disk yang dikuasai Docker di mesin ini. Sepanjang section kita menarik image demi image, membangun myapp sendiri, menyimpan arsip untuk dibawa ke mesin lain, dan setiap kegiatan itu meninggalkan jejak — image yang tidak lagi terpakai, cache build yang menumpuk diam-diam, sampai volume anonim yang lahir tanpa diminta. Tabel docker images hanya menampilkan penghuni satu jenis; yang kita butuhkan adalah peta seluruh wilayah. Chapter ini membangun peta itu dengan docker system df, membaca rinciannya sampai ke layer yang dibagikan dua image, lalu membereskannya dengan keluarga perintah prune — dari yang paling selektif sampai yang paling rakus — sebelum menutup section dengan mesin yang benar-benar terkendali.
Peta Ruang Disk dengan docker system df #
Sebelum membersihkan, kita kumpulkan dulu bahan perceritaan. Dua kegiatan kecil sengaja kita lakukan: Budi menyunting app.sh lalu membangun ulang myapp:dev — persis Dockerfile lima instruksi dari Chapter Image Inspect dan History — dan menjalankan satu container alat sekali jalan yang menulis berkas ke sebuah path yang di-mount kosong:
$ docker build -t myapp:dev .Output yang Dihasilkan:
[+] Building 0.9s (9/9) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 148B 0.0s
=> [internal] load metadata for docker.io/library/alpine:3.20 0.3s
=> [1/4] FROM docker.io/library/alpine:3.20 0.0s
=> CACHED [2/4] RUN apk add --no-cache curl 0.0s
=> CACHED [3/4] WORKDIR /app 0.0s
=> [4/4] COPY app.sh /app/app.sh 0.1s
=> exporting layers 0.1s
=> => writing image sha256:37f03018eb2a68b7941e631ddc243ef670401fae451440428328615abc2d4faa 0.1s
=> => naming to docker.io/library/myapp:dev 0.0s$ docker run --name uji-data -v /data alpine:3.20 sh -c 'echo percobaan > /data/catatan.txt'Dua kejadian penting baru saja tersembunyi di balik dua perintah itu, dan keduanya akan terbaca pada peta kita nanti. Build ulang dengan tag yang sama menandai peristiwa lama dari Chapter Melihat Image Lokal: image myapp:dev yang lama kehilangan namanya dan menjadi image menganggur. Adapun flag -v /data dengan satu path tanpa nama — pola yang akan kita bedah tuntas pada Section Penyimpanan Data — melahirkan volume anonim yang menampung catatan.txt. Sekarang kita lihat seluruh wilayahnya:
$ docker system dfOutput yang Dihasilkan:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 5 1 241.4MB 54.4MB (22%)
Containers 2 1 6.9MB 0B (0%)
Local Volumes 2 1 4.1kB 0B (0%)
Build Cache 4 0 6.6MB 6.6MB (100%)Mari kita telaah keempat baris tersebut satu per satu:
Images— 5 image seluas 241.4MB — nginx:latest, nginx:1.29-alpine hasildocker loadpada chapter sebelumnya, alpine:3.20, myapp:dev yang baru, dan satu image menganggur tanpa nama. Hanya satu yang ACTIVE karena hanya nginx:latest yang dipakai container web; angka SIZE lebih jujur daripada penjumlahan kolom SIZE padadocker imageskarena layer yang dibagikan — fondasi alpine yang dipakai tiga image sekaligus — dihitung sekali, persis catatan kita pada Chapter Melihat Image Lokal.Containers— 2 buah, 6.9MB — container web yang berjalan dan uji-data yang sudah selesai; seluruh angka ini adalah writable layer mereka. RECLAIMABLE 0B karena writable layer container berhenti baru benar-benar lepas saat container-nya dihapus.Local Volumes— 2 buah, 4.1kB — volume anonim milik uji-data berisi catatan.txt serta latihan-volume kosong ciptaan Chapter Struktur Perintah Docker yang selama ini tidak pernah kita sentuh lagi. ACTIVE dihitung dari container yang memakainya: satu untuk si anonim, nol untuk latihan-volume.Build Cache— 4 rekaman, 6.6MB — simpanan BuildKit dari dua sesi build myapp; tidak ada build yang sedang berjalan, maka seluruhnya RECLAIMABLE.
Rincian dengan docker system df -v #
Ringkasan empat baris menjadi peta lengkap dengan flag -v — output-nya panjang, jadi berikut bagian-bagian yang relevan dipotong:
$ docker system df -vOutput yang Dihasilkan (dipotong):
Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
nginx latest 613f27b0341a 4 days ago 187MB 0B 187MB 1
nginx 1.29-alpine 5b1e8c3a9f7d 4 days ago 47.9MB 7.8MB 40.1MB 0
alpine 3.20 2676beef0bef 2 weeks ago 7.8MB 7.8MB 0B 0
myapp dev 37f03018eb2a 22 seconds ago 14.2MB 14.2MB 129B 0
<none> <none> 93ba1c630022 About an hour ago 14.2MB 14.2MB 129B 0
Containers space usage: (dipotong)
Local Volumes space usage:
VOLUME NAME LINKS SIZE
0caad03ea96e786fb64f602246ddb927ca6c17adfd1774953cbcd414ffabcae3 1 4.1kB
latihan-volume 0 0B
Build cache usage: (dipotong)Mari kita telaah tiga bagian yang paling berharga dari rincian tersebut:
- Kolom SHARED SIZE dan UNIQUE SIZE — myapp:dev yang baru berbagi 14.2MB dengan image lain: fondasi alpine 7.8MB dan layer curl 6.42MB yang sama-sama dipakai image myapp lama. UNIQUE SIZE-nya hanya 129B — satu berkas
app.shversi baru. Image menganggur<none>menampilkan cermin yang sama: 14.2MB dibagikan, 129B milik sendiri. - Kolom LINKS pada volume — jumlah container yang memasang volume tersebut; volume anonim dengan nama heksadesimal 64 karakter diikat oleh satu container, sementara latihan-volume telah lama ditinggalkan pemiliknya dengan LINKS 0.
- Kontainer dan cache ikut dirinci — bagian yang dipotong memuat writable layer tiap container dan rekaman cache BuildKit satu per satu; keduanya menjadi penting saat kita menilik volume dan build cache pada bagian berikutnya.
Angka UNIQUE SIZE 129B pada image menganggur itu adalah petunjuk penting untuk pembersihan pertama kita: image 14.2MB itu ternyata hanya “menanggung” 129B miliknya sendiri.
Memangkas Image dengan docker image prune #
Perintah paling selektif di keluarga prune menyasar image menganggur — yang kehilangan nama setelah build ulang:
$ docker image pruneOutput yang Dihasilkan:
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
Deleted: sha256:93ba1c6300227dd7ac8685969f432f61645f99b7a904a0224b384df9cb238330
Total reclaimed space: 129BMari kita telaah hasil yang tampak kecil itu:
Total reclaimed space: 129B— bukan 14.2MB seperti ukuran image pada tabel. Layer fondasi alpine dan layer curl masih melayani myapp:dev yang baru, sehingga yang benar-benar bebas hanya layerapp.shlama seukuran 129B — perilaku berbagi layer dari Chapter Konsep Image Layer bekerja sampai ke hitungan pembersihan.- Konfirmasi
[y/N]— seluruh keluarga prune bersifat massal dan tidak bisa dibatalkan; kebiasaan membaca petadflebih dulu adalah pagar kita. - Image bertag tidak tersentuh — varian ini hanya menyasar image tanpa nama; nginx, alpine, dan myapp:dev tetap utuh.
Varian jauh lebih agresif menambahkan flag -a — semua image tanpa container yang memakainya:
$ docker image prune -aOutput yang Dihasilkan (dipotong):
WARNING! This will remove all images without at least one container associated with them.
Are you sure you want to continue? [y/N] y
Untagged: nginx:1.29-alpine
Untagged: nginx@sha256:6d9f2c8a4e7b1d5f3c9a2e8b7d4f1c6a9e3b5d7f2c8a4e1b6d9f3c7a5e2b8d1f
Deleted: sha256:5b1e8c3a9f7d...
...
Total reclaimed space: 54.3MBTiga image berangkat — nginx:1.29-alpine, alpine:3.20, dan myapp:dev — dan nginx:latest bertahan karena container web masih memakainya. Angka 54.3MB adalah seluruh isi unik ketiganya setelah layer bersama dihitung sekali. Kedua varian ini menerima penyaring --filter untuk pembersihan yang lebih sempit:
| Bentuk perintah | Sasaran | Contoh kasus |
|---|---|---|
docker image prune | hanya image menganggur | rutinitas harian setelah beberapa kali build ulang |
docker image prune -a | semua image tanpa pemakai | merapikan mesin latihan atau runner CI sekali pakai |
docker image prune -a --filter until=24h | image tanpa pemakai yang dibuat lebih dari 24 jam lalu | menyisakan image hasil build hari ini |
docker image prune -a --filter label=lingkup=latihan | image tanpa pemakai yang ber-label cocok | membereskan artefak satu proyek tanpa menyentuh yang lain |
Filter label=lingkup=latihan membaca metadata LABEL image — instruksi yang akan kita bahas pada Chapter VOLUME dan LABEL — sehingga proyek yang menandai imagenya sendiri bisa dibersihkan sendiri pula.
Memangkas Build Cache dengan docker builder prune #
Baris Build Cache pada peta kita masih memegang 6.6MB. Pembersihnya satu perintah:
$ docker builder pruneOutput yang Dihasilkan:
WARNING! This will remove all dangling build cache.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 6.6MBEmpat rekaman cache dari dua sesi build myapp terhapus sekaligus. Konsekuensinya perlu dipahami dengan sadar: build myapp berikutnya tidak lagi menikmati CACHED pada langkah RUN apk add dan harus mengeksekusinya dari nol — harga beberapa detik yang kita bayar demi 6.6MB ruang. Pada mesin CI yang membangun ratusa proyek, angka cache ini bisa mencapai gigabita dan penyaring --filter until= menjadi penyelamat rutinitas — materi yang kita perdalam nanti pada Chapter Build Cache di Section Image Build dan Optimisasi.
Memangkas Volume dengan docker volume prune #
Sisa cerita kita tinggal dua objek: container uji-data yang sudah selesai beserta volume anonimnya. Container-nya dibuang lebih dulu:
$ docker rm uji-dataOutput yang Dihasilkan:
31ec07b651442ce31518fad8bbe6e0b578ec37aa118954a49365e9f85b39ec19Volume anonimnya kini yatim — LINKS 0 pada peta df -v kita. Keluarganya:
$ docker volume pruneOutput yang Dihasilkan:
WARNING! This will remove all anonymous volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
0caad03ea96e786fb64f602246ddb927ca6c17adfd1774953cbcd414ffabcae3
Total reclaimed space: 4.1kBMari kita telaah dua hal pada output kecil itu:
- Volume anonim saja yang disentuh — peringatan di baris pertama menyebut sasarannya secara eksplisit; latihan-volume selamat karena bawaannya memang tidak membuang volume bernama. Membersihkan volume bernama menuntut
--all— dan menuntut keberanian yang lebih besar, karena volume adalah tempat data hidup. - 4.1kB adalah catatan.txt — kecil hari ini, tetapi volume database produksi bisa berukuran puluhan gigabita; kebiasaan membaca
docker volume lssebelumyadalah pagar yang sama seperti membaca df sebelum prune image.
Penggabung Semuanya: docker system prune #
Semua pembersih di atas punya satu perintah gabungan:
$ docker system pruneOutput yang Dihasilkan:
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all build cache
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0BAngka 0B bukan kegagalan — justru bukti bahwa pembersihan kita barusan menyapu bersih. docker system prune menggabungkan sasaran: container berhenti, jaringan tanpa penghuni, image menganggur, dan build cache. Dua varian menaikkan taruhannya: -a meluaskan image menjadi semua yang tanpa pemakai, dan --volumes menambahkan volume anonim yang tak terpakai ke dalam sapuan.
Peta akhir kita menutup bukti kebersihan:
$ docker system dfOutput yang Dihasilkan:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 187MB 0B (0%)
Containers 1 1 6.9MB 0B (0%)
Local Volumes 1 0 0B 0B (0%)
Build Cache 0 0 0B 0BMesin latihan kita kini memegang tepat satu image, satu container, satu volume kosong, dan nol cache — penyimpanan lokal dalam kondisi terkendali. Namun kondisi bersih ini juga memperlihatkan ketimpangan yang lebih besar: sepanjang dua section terakhir kita berperan sebagai konsumen — menarik, menandai, memeriksa, mendistribusikan, dan membersihkan image buatan orang lain, dan satu-satunya image buatan sendiri hanyalah mainan lima baris. Kekuatan sesungguhnya Docker menunggu di sebelah sana: mengemas aplikasi kita sendiri menjadi image yang bisa menyala di mesin mana pun. Section berikutnya memindahkan kita ke kursi produsen — dan lembar pertamanya adalah berkas kecil bernama Dockerfile.
Referensi #
- docker system df — CLI Reference
— format ringkasan dan rincian
-vuntuk seluruh jenis objek. - docker image prune — CLI Reference
— varian pembersihan image beserta penyaring
untildanlabel. - docker builder prune — CLI Reference — pembersihan build cache beserta flag penyaringnya.
- docker system prune — CLI Reference
— penggabungan pembersihan dan varian
-aserta--volumes.