Skip to main content
DevOps dari nol · Pelajaran 15 dari 15 · 12 menit

Docker No Space Left on Device: Cari Penyebab Disk Penuh

Atasi no space left on device di Docker: baca docker system df, prune image dan build cache menurut usia, simpan N image terbaru, batasi log, journal.

Oleh Matthews WongDitinjau pada

Poin utama

No space left on device di host Docker berarti ada yang tumbuh tanpa batas: image bertag dari setiap deploy, build cache, log container, journal systemd, atau volume. Ukur dulu dengan df, docker system df, dan journalctl --disk-usage. Lalu prune berdasarkan usia atau jumlah, batasi log dan journal, dan jangan sentuh volume.

Setelah pelajaran ini, Anda bisa

  • Menemukan mana yang memakai disk, image, build cache, log, journal, atau volume, sebelum menghapus apa pun.
  • Memilih perintah prune yang tepat, dan menyebut mana yang menghapus data.
  • Membatasi yang tumbuh sendiri: simpan N image terbaru, rotasi log container, dan vacuum journal.
Lihat cara kerjanya

Ikuti diagramnya langkah demi langkah

Tekan Putar, atau melangkah dengan panah. Setiap langkah juga ditulis di bawah diagram.

Apa yang memenuhi disk host Docker, dan apa yang membebaskannya

Lima hal memenuhi disk: image, build cache, log container, journal, dan volume. Masing-masing punya perintah sendiri untuk mengukur atau membatasinya, dan volume satu-satunya yang tidak boleh di-prune otomatis.

Langkah 1 dari 7. Di kiri, lima hal yang tumbuh di host Docker. Di kanan, perintah untuk mengukur atau membatasi masing-masing. Ukur dulu, lalu pilih pembersihan terkecil yang cukup.

Tombol: ← → langkah · Home / End · K putar atau jeda

  1. Di kiri, lima hal yang tumbuh di host Docker. Di kanan, perintah untuk mengukur atau membatasi masing-masing. Ukur dulu, lalu pilih pembersihan terkecil yang cukup.

  2. docker system df merangkum ruang yang dipakai image, container, dan volume lokal. Tambahkan -v untuk tiap item. Log dan journal diukur di tempat lain, dengan du dan journalctl --disk-usage.

    docker system df -v
  3. docker image prune -a menghapus image yang tidak dipakai container. Dengan until=72h hanya yang lebih tua dari 72 jam. docker builder prune menerima filter until yang sama untuk build cache.

    docker image prune -af --filter "until=72h"Tebak langkah berikutnya Hari yang sibuk membawa 19 deploy dalam 40 jam. Apa yang dihapus prune 72 jam? (Semua rilis lama · Tidak ada: semua image berusia di bawah 72 jam · Hanya image dangling)
  4. Karena itu deploy juga membatasi dengan jumlah: daftar image aplikasi dari yang terbaru, lewati dua pertama, hapus sisanya. docker image rm menolak image yang dipakai container.

    docker image ls | sort -r | tail -n +3 | xargs -r docker image rm
  5. Driver json-file secara default tanpa batas max-size dan satu file, dan max-file hanya bekerja bersama max-size. File compose menyetel 10m dan 3, jadi tiap log berotasi.

    max-size: "10m" max-file: "3"
  6. journalctl --vacuum-size menghapus file journal arsip tertua sampai muat dalam batas. File aktif tetap ada, jadi --disk-usage masih bisa lebih besar dari target.

    journalctl --disk-usage sudo journalctl --vacuum-size=200MTebak langkah berikutnya Apakah docker system prune tanpa flag menghapus volume? (Ya, semua volume yang tidak dipakai · Tidak, volume tidak di-prune secara default · Hanya volume bernama)
  7. Docker tidak pernah menghapus volume sendiri, karena bisa menghilangkan data. docker volume prune menghapus volume anonim yang tidak dipakai; yang bernama butuh --all. Deploy tidak pernah menjalankannya.

Apa yang memenuhi disk host Docker?

Lima hal tumbuh di host Docker, dan sebagian tumbuh diam-diam. Image menumpuk karena setiap deploy menarik tag baru, dan image bertag bukan dangling: Docker mendefinisikan image dangling sebagai image tanpa tag yang tidak dirujuk container mana pun. Build cache bertambah di setiap build. Log container tidak punya batas sampai Anda menyetelnya. Journal systemd dan volume memegang sisanya.

Baca selengkapnya (1)

Error yang memberi tahu Anda adalah no space left on device, biasanya di tengah pull image atau build, bukan di saat tenang. Karena itu situs ini mencetak df sebelum dan sesudah langkah pembersihannya: log lalu menunjukkan berapa banyak ruang yang benar-benar didapat tiap langkah.

Bagaimana menemukan apa yang memakai ruang?

Mulai dengan df -h pada filesystem yang penuh, supaya Anda tahu seberapa parah. Lalu docker system df, yang oleh Docker dijelaskan sebagai ruang yang dipakai daemon, dalam baris untuk image, container, dan volume lokal. Tambahkan -v dan setiap image, container, dan volume mendapat barisnya sendiri, lengkap dengan ukuran unik yang hanya dipakai satu image dan ukuran yang dibagi dengan yang lain.

Baca selengkapnya (1)

Angka Docker sendiri tidak mencakup journal. Untuk itu, journalctl --disk-usage melaporkan total semua file journal arsip dan aktif. Baca keduanya sebelum menghapus apa pun: baris terbesar biasanya jelas, dan itu memberi tahu bagian mana di bawah yang dipakai.

Apa yang dihapus tiap perintah prune?

Perintah prune berbeda cakupannya, dan tabel di bawah menyandingkannya. Dua flag mengubah jawabannya: -a memperluas image prune dari image dangling ke setiap image yang tidak dipakai container, dan filter seperti until=24h membatasi prune ke item yang lebih tua dari usia yang Anda beri. Tiap perintah meminta konfirmasi kecuali Anda memberi -f, jadi membaca prompt adalah kesempatan terakhir Anda.

Bagaimana menyimpan hanya N image terakhir?

Filter usia mengandaikan laju deploy yang stabil. Deploy situs ini begitu, sampai 19 deploy masuk dalam 40 jam: setiap image berusia kurang dari 72 jam, prune tidak menghapus apa pun, dan disk mencapai 93%. Perbaikannya adalah batas jumlah di samping filter usia: daftar image aplikasi dari yang terbaru, lewati dua pertama, dan hapus sisanya dengan docker image rm.

Baca selengkapnya (1)

Dua sifat membuatnya aman. docker image rm menolak menghapus image milik container yang sedang berjalan kecuali Anda memaksanya, jadi rilis yang aktif selamat. Dan menghapus image dari host tidak menghapusnya dari registry, jadi rilis lama bisa ditarik lagi bila perlu.

Bagaimana membatasi log dan journal?

Untuk log container, solusinya adalah pengaturan, bukan pembersihan. max-size pada driver json-file secara default -1, tanpa batas, dan max-file default 1 serta hanya berlaku bila max-size disetel. File compose situs ini menyetel 10m dan 3, jadi container menyimpan paling banyak tiga file log masing-masing hingga 10 MB.

Baca selengkapnya (1)

Journal punya dua alat. journalctl --vacuum-size, --vacuum-time, dan --vacuum-files membersihkannya sekali: menghapus file journal arsip berdasarkan total ukuran, usia, atau sampai jumlah file tertentu. SystemMaxUse= di journald.conf membatasinya secara permanen, dan secara default journald memakai hingga 10% filesystem, dibatasi 4G. Pakai vacuum untuk pulih sekarang dan pengaturan itu agar masalahnya tidak kembali.

Cara situs ini melakukannya

Konfigurasi nyata di balik pelajaran ini

Kutipan dari repositori yang membangun dan men-deploy situs ini, apa adanya.

.github/workflows/deploy.yml:262-275
            # The 72h window assumes a few deploys a day. On 2026-10-13/14 there
            # were 19 in 40 hours, every image was younger than 72h, so the
            # prune above removed nothing and the disk reached 93%. So the
            # portfolio's own images are also capped by count: the newest two
            # are the running release and the one a rollback needs. Older
            # releases stay in GHCR. `docker image rm` refuses an image a
            # container still uses, so a rolled-back release is never removed.
            KEEP_PORTFOLIO_IMAGES=2
            PORTFOLIO_REPO="${{ needs.build-and-push.outputs.image }}"
            PORTFOLIO_REPO="${PORTFOLIO_REPO%:*}"
            docker image ls "$PORTFOLIO_REPO" --format '{{.CreatedAt}}\t{{.Repository}}:{{.Tag}}' \
              | sort -r | tail -n +$((KEEP_PORTFOLIO_IMAGES + 1)) | cut -f2 \
              | xargs -r docker image rm || true
            df -h / | tail -1

Batas jumlah yang berada setelah filter usia. docker image ls dengan sort -r menghasilkan urutan terbaru dulu, tail -n +3 melewati dua yang dipertahankan, dan xargs -r docker image rm menghapus sisanya. || true di ujung berarti penghapusan yang ditolak tidak menggagalkan deploy, dan baris terakhir mencetak disk supaya log menunjukkan hasilnya.

docker-compose.yml:43-47
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

Batas untuk log container. Tanpa max-size driver json-file tidak pernah merotasi, karena defaultnya tanpa batas. Dengan itu, Docker memutar file pada 10 MB dan menyimpan tiga, jadi container yang berisik tidak lagi bisa menjadi penyebab disk penuh.

Yang sering rusak

Kesalahan yang benar-benar membuang waktu

  • Destruktif: volume prune dan system prune --volumes menghapus data

    docker volume prune menghapus volume anonim yang tidak dipakai, docker volume prune --all juga menghapus yang bernama, dan docker system prune --volumes menambahkan volume anonim ke system prune. Begitu tidak ada yang merujuk sebuah volume, volume itu bisa dihapus. Karena itu Docker tidak pernah menghapus volume sendiri, jadi jangan masukkan ke skrip pembersihan.

  • Destruktif: prune -a tanpa filter menghapus image untuk rollback

    docker image prune -a menghapus setiap image yang tidak dipakai container, bertag atau tidak, dan docker system prune -a melakukan hal yang sama ditambah yang lain. Rilis sebelumnya tidak sedang dipakai, jadi ikut terhapus, dan rollback harus menariknya lagi. Tambahkan filter until atau batas jumlah, seperti yang dilakukan deploy.

  • Filter waktu saja gagal di hari yang sibuk

    until=72h hanya menghapus image yang lebih tua dari 72 jam. Ketika banyak deploy masuk dalam jendela itu, tidak ada yang memenuhi syarat dan prune tidak membebaskan apa pun walau log tetap tampak sukses. Batasi juga dengan jumlah, dan cetak df setelah pembersihan agar prune yang tidak berefek terlihat.

  • Log tanpa max-size, atau max-file saja

    Container tanpa max-size menyimpan satu file log yang membesar sampai disk penuh, dan tidak ada perintah prune yang menyentuhnya. Menyetel max-file saja tidak berefek, karena hanya berlaku bila max-size juga disetel. Setel keduanya, dan ingat bahwa journal dibatasi secara terpisah.

  • Vacuum sudah dijalankan, tetapi journal masih melebihi batas

    --vacuum-size hanya menghapus file journal arsip, sedangkan --disk-usage menghitung yang arsip dan aktif. File aktif bisa membuat total tetap di atas target. Itu wajar, bukan perintah yang gagal; batas SystemMaxUse= yang menjaga journal tetap terbatas dari waktu ke waktu.

Apa yang dihapus tiap perintah pembersihan Docker. Default menurut dokumentasi Docker.
docker image pruneImage dangling: tanpa tag dan tidak dipakaiTidak, image bisa ditarik lagi
docker image prune -aSetiap image yang tidak dipakai container, termasuk yang bertagTidak, tetapi kehilangan image rollback lokal
docker container pruneSemua container yang berhentiYa, container yang berhenti dihapus
docker builder pruneBuild cache dangling; -a menghapus semua cache yang tidak dipakaiTidak, hanya build berikutnya lebih lambat
docker system pruneContainer berhenti, network tidak dipakai, image dangling, build cache tidak dipakaiYa, container yang berhenti ikut terhapus
docker volume pruneVolume anonim yang tidak dipakai; --all menambah yang bernamaYa, ini data yang tersimpan
Coba sendiri

Lakukan di komputer Anda sendiri

Pakai mesin latihan, bukan host produksi. Anda butuh Docker dan mesin Linux dengan systemd. Lihat dulu, hapus kemudian.

  1. Periksa seberapa penuh disk dan apa yang menurut Docker dipakainya.

    df -h /
    docker system df
  2. Ambil daftar per item. Catat image mana yang menunjukkan 0 container: itulah yang bisa dijangkau prune.

    docker system df -v
  3. Periksa journal, yang tidak ditampilkan docker system df.

    journalctl --disk-usage
  4. Prune image yang lebih tua dari 72 jam. Baca prompt konfirmasinya sebelum menjawab, dan jangan menambahkan --volumes di mana pun.

    docker image prune -a --filter "until=72h"
  5. Vacuum journal ke ukuran tertentu, lalu jalankan lagi perintah pemakaiannya dan bandingkan.

    sudo journalctl --vacuum-size=200M
    journalctl --disk-usage
Kuis singkat

Tiga pertanyaan sebelum lanjut

Pilih jawaban untuk melihat kenapa benar atau salah. Tidak ada yang disimpan atau dinilai, jadi tebak saja dengan bebas.

  1. 1.Deploy menjalankan docker image prune -af --filter until=72h, tetapi disk penuh setelah 19 deploy dalam 40 jam. Kenapa prune tidak membebaskan apa pun?
  2. 2.Anda menjalankan journalctl --vacuum-size=200M, tetapi --disk-usage masih menunjukkan lebih dari 200M. Apa penjelasannya?
  3. 3.Perintah mana yang menghapus volume bernama yang tidak dipakai, sehingga bisa menghilangkan data?
Pikirkan dulu

Jawab dalam hati, lalu cek

  1. 1.Kenapa image bertag dari minggu lalu tidak dihapus oleh docker image prune biasa?Lihat jawabannya

    Jawaban:image prune biasa hanya menghapus image dangling, yaitu tanpa tag dan tidak dirujuk. Setiap deploy menarik tag baru, jadi rilis lama bertag dan bertahan sampai Anda menambah -a atau menghapusnya menurut jumlah.

  2. 2.Dua batas apa yang disetel file compose pada log container, dan apa yang terjadi tanpa yang pertama?Lihat jawabannya

    Jawaban:max-size 10m dan max-file 3. Tanpa max-size driver json-file tanpa batas, dan max-file diabaikan, jadi log membesar sampai disk penuh.

  3. 3.Kenapa aman bagi pembersihan menjalankan docker image rm pada rilis yang lebih lama?Lihat jawabannya

    Jawaban:Perintah itu menolak image yang dipakai container yang berjalan, dan menghapusnya dari host tidak menyentuh salinan di registry. Dua image terbaru dipertahankan, dan rilis lain bisa ditarik lagi.

Pelajari lebih dalam

Bahasan mendalam terkait di situs ini