Cara Kosongkan Ruang Cakera Docker pada VPS
VPS anda penuh disebabkan Docker? Ketahui cara mengenal pasti penggunaan ruang oleh imej, kontena, cache binaan atau volum dan bersihkan data dengan selamat tanpa kehilangan fail.
Kenal pasti penggunaan ruang cakera sebelum anda memadam apa-apa
Docker menggunakan ruang cakera pada VPS di empat lokasi: imej, kontena yang dihentikan, cache binaan, dan volum tempatan. Jalankan docker system df terlebih dahulu untuk mengetahui bahagian mana yang memakan ruang, kemudian jalankan arahan pembersihan yang paling khusus untuk mengosongkannya. Urutan adalah penting, kerana arahan terakhir dalam panduan ini, docker volume prune -a, akan memadam data dan tiada cara untuk membatalkannya.
Mulakan dengan sistem fail, bukan dengan Docker.
df -h /
sudo du -xh --max-depth=1 /var/lib/docker | sort -hdf memberitahu anda tahap penggunaan ruang. du memberitahu anda ke mana ruang tersebut pergi. Flag -x mengekalkan du pada satu sistem fail, supaya ia tidak mengikuti mount ke dalam volum berasingan dan mengiranya dua kali. Lima direktori penting di sini: overlay2 menyimpan lapisan imej dan kontena, volumes menyimpan data volum, containers menyimpan metadata kontena dan fail log, buildkit menyimpan cache binaan, dan image menyimpan metadata lapisan.
Nota mengenai sudo dan wildcard shell, kerana ia sering membuang masa pengguna. /var/lib/docker dimiliki oleh root dan tidak boleh dibaca oleh pengguna biasa anda, jadi ls /var/lib/docker akan memaparkan Permission denied. Arahan seperti sudo du -sh /var/lib/docker/* juga akan gagal, kerana shell anda mengembangkan * sebelum sudo sempat dijalankan, dan shell anda tidak mempunyai kebenaran untuk membaca direktori tersebut. Setiap arahan di bawah menggunakan find atau --max-depth sebagai ganti wildcard atas sebab tersebut.
Sekarang, lihat pandangan Docker sendiri.
docker system dfTYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 24 6 12.4GB 8.91GB (71%)
Containers 31 6 1.42GB 1.39GB (97%)
Local Volumes 14 5 6.03GB 4.11GB (68%)
Build Cache 212 0 9.87GB 9.87GBAngka-angka tersebut datang daripada satu mesin dan tidak menggambarkan keadaan mesin anda. Baca corak datanya. TOTAL mengira objek, ACTIVE mengira objek yang sedang digunakan, dan RECLAIMABLE adalah anggaran Docker tentang jumlah ruang yang boleh dikosongkan melalui pembersihan.
Dua perkara mengenai RECLAIMABLE sering memerangkap pengguna. Ia mengira lapisan imej yang dikongsi sekali bagi setiap imej yang menggunakannya, jadi baris imej biasanya menjanjikan ruang yang lebih besar daripada yang akan anda perolehi. Ia juga tidak pernah menyertakan fail log kontena, kerana Docker tidak menganggap fail log sebagai objek yang boleh dituntut semula. Apabila du melaporkan direktori yang jauh lebih besar daripada yang diakui oleh docker system df, fail log adalah puncanya, dan terdapat bahagian mengenai perkara itu di bawah.
Tambahkan -v untuk perincian setiap objek.
docker system df -vIni memecahkan ringkasan kepada satu bahagian bagi setiap jenis objek. Bahagian imej menambah lajur SHARED SIZE dan UNIQUE SIZE, supaya anda boleh melihat kos sebenar bagi satu imej. Bahagian volum menambah kiraan LINKS, iaitu bilangan kontena yang disambungkan kepada volum tersebut. Ingat LINKS, kerana nilai 0 adalah ujian utama bagi menentukan sama ada arahan pembersihan volum boleh digunakan.
Imej tergantung berbanding imej tidak digunakan
Kedua-dua istilah ini kelihatan boleh ditukar ganti, namun sebenarnya tidak. Penapis berkelakuan berbeza kerana objeknya juga berbeza.
Imej tergantung (dangling image) ialah imej tanpa tag. Ia dipaparkan sebagai <none> dalam docker images. Anda mencipta satu imej sedemikian pada setiap binaan semula: docker build -t myapp:latest . mengalihkan tag myapp:latest ke imej baharu, manakala imej lama mengekalkan semua layernya tetapi kehilangan namanya. Tiada apa-apa yang merujuk kepadanya, dan tiada proses automatik yang membersihkannya.
Imej tidak digunakan (unused image) ialah sebarang imej, sama ada bertag atau tidak, yang tidak dirujuk oleh mana-mana kontena pada masa ini. Imej postgres:16 yang anda tarik bulan lepas dan tidak dijalankan sekarang adalah tidak digunakan, dan ia bukan imej tergantung.
docker image prune # dangling images only
docker image prune -a # every image no container refers toPerintah kedua akan meminta pengesahan terlebih dahulu.
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N]Baca gesaan tersebut dengan teliti. "Associated to them" bermaksud objek kontena yang sedia ada, sama ada sedang berjalan atau dihentikan. Jika anda menjalankan docker compose down, kontena tersebut telah tiada, jadi setiap imej yang digunakan oleh servis tersebut kini tidak digunakan, dan -a akan memadamkan kesemuanya. Tiada data yang hilang yang tidak boleh diperoleh semula, tetapi docker compose up -d yang seterusnya akan menarik atau membina semula kesemuanya, yang memakan lebar jalur dan masa binaan pada VPS kecil. Itu adalah satu sebab praktikal untuk mengetahui apa yang docker compose down buang dan apa yang stop biarkan berjalan sebelum anda melakukan sebarang pembersihan (prune).
Satu penapis mengekalkan imej baharu di luar skop pembersihan.
docker image prune -a --filter "until=240h"Perintah itu memadamkan imej tidak digunakan yang dicipta lebih daripada 240 jam (10 hari) yang lalu dan membiarkan imej yang lebih baharu. Nilai until menerima rentetan tempoh Go seperti 240h, atau cap waktu mutlak seperti 2026-08-01T00:00:00.
Apakah cache binaan dan mengapa ia membesar tanpa had
BuildKit ialah pembina yang digunakan oleh Docker secara lalai untuk docker build dan docker compose build sejak Docker Engine 23.0. Ia menyimpan cache bagi setiap langkah dalam setiap Dockerfile yang dijalankan, dan ia menyimpan cache tersebut di dalam /var/lib/docker/buildkit. Cache inilah sebabnya binaan kedua anda selesai dalam beberapa saat, jadi ia menjalankan fungsinya dengan baik. Masalahnya ialah tiada mekanisme yang memadamkan entri lama secara lalai. Jika anda membina imej yang sama sebanyak lima puluh kali dengan langkah COPY yang berubah setiap kali, anda akan menyimpan lima puluh set lapisan.
Cache binaan tidak kelihatan kepada docker image prune. Ia merupakan jenis objek berasingan dengan arahannya yang tersendiri.
docker builder prune # dangling cache
docker builder prune -a # all unused cache
docker builder prune --filter until=168h # cache untouched for 7 daysTiada satu pun daripada arahan ini akan menyentuh imej atau data anda. Satu-satunya kesan daripada mengosongkan cache binaan ialah binaan seterusnya akan berjalan perlahan buat sekali sahaja. Pada VPS yang membina semula imej secara kerap, Build Cache sering menjadi baris terbesar dalam docker system df, yang menjadikannya perkara besar paling selamat untuk anda padamkan.
Perintah prune, disusun daripada yang selamat kepada yang merosakkan
Ikuti senarai ini dan berhenti sebaik sahaja df -h / kelihatan sihat semula. Setiap perintah akan mencetak baris Total reclaimed space: apabila ia selesai.
docker container prunemembuang kontena yang telah berhenti. Lapisan boleh tulisnya juga akan dibuang, jadi apa-apa yang ditulis oleh kontena di luar volume akan dipadam bersamanya. Volume tidak disentuh.docker image prunehanya membuang imej yang tergantung (dangling). Ini adalah perintah imej yang paling selamat.docker builder prunemembuang cache binaan yang tergantung. Kosnya ialah satu binaan yang perlahan.docker image prune -amembuang setiap imej yang tidak dirujuk oleh mana-mana kontena. Kosnya ialah proses menarik semula (re-pull) atau membina semula (rebuild).docker system prunemelakukan tiga langkah pertama serentak dan menambah rangkaian yang tidak digunakan.docker volume prunemembuang volume tanpa nama yang tidak digunakan.docker volume prune -amembuang volume yang tidak digunakan termasuk yang mempunyai nama. Ini adalah perintah yang memadam pangkalan data.
docker system prune menyatakan skopnya sendiri sebelum ia dijalankan.
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- unused build cache
Are you sure you want to continue? [y/N]Volume sengaja tidak dimasukkan dalam senarai itu. Menambah --volumes akan memasukkan semula volume tanpa nama ke dalam skop. Menambah -a meluaskan langkah imej daripada imej tergantung kepada setiap imej yang tidak digunakan. docker system prune -a --volumes -f penuh pada hos pengeluaran (production host) adalah punca kehilangan data semasa cuba mengosongkan ruang storan.
Mengapa pembersihan volume memadamkan pangkalan data anda
Ini adalah bahagian yang perlu dibaca dua kali.
Sesuatu volume dianggap tidak digunakan apabila tiada container yang dipasang padanya. Itulah satu-satunya ujian yang dilakukan. Docker tidak menyemak sama ada volume tersebut kosong, sama ada fail compose masih mengisytiharkannya, atau sama ada ia menyimpan satu-satunya salinan pangkalan data anda. LINKS 0 dalam docker system df -v bermaksud boleh dibersihkan, dan ia tidak bermaksud apa-apa yang lain.
Sekarang, bayangkan dua tindakan biasa dilakukan berturut-turut. Anda menjalankan docker compose down untuk memulakan semula stack dengan bersih. Tindakan ini membuang container dan membiarkan named volume di tempatnya, yang memang merupakan fungsi yang didokumentasikan. Volume Postgres anda kini tidak dipasang pada apa-apa. Sepuluh minit kemudian, anda menjalankan docker volume prune -a untuk mengosongkan ruang, dan pangkalan data tersebut hilang. Kedua-dua arahan berkelakuan dengan betul. Urutan tersebut telah memusnahkan data.
Sejak Docker Engine 23.0 (API version 1.42), arahan biasa tersebut adalah lebih terhad berbanding sebelumnya.
WARNING! This will remove anonymous local volumes not used by at least one container.Anonymous volume ialah volume yang dicipta oleh Docker untuk anda, biasanya kerana imej mengisytiharkan VOLUME dan anda tidak pernah memberikan nama kepadanya. Volume tersebut biasanya menyimpan data yang anda tidak minta untuk disimpan. Named volume, iaitu jenis yang anda tulis ke dalam fail compose anda, hanya akan dibuang apabila anda menambah -a. Versi Docker yang lebih lama membuang kedua-duanya dengan arahan biasa, jadi jangan percayai tabiat yang terbentuk pada mesin yang telah anda naik taraf. Perbezaan ini hanya masuk akal apabila anda mengetahui bagaimana named volume berbeza daripada bind mount, kerana bind mount bukanlah Docker volume dan tiada arahan prune yang akan menyentuhnya.
Lihat dahulu sebelum anda memadam. Gantikan myapp_pgdata dengan nama volume yang anda sedang semak.
docker volume ls -f dangling=true
docker volume inspect myapp_pgdata
sudo ls -la /var/lib/docker/volumes/myapp_pgdata/_dataPenapis dangling=true pada volume bermaksud tidak dirujuk, bukan kosong. Menyenaraikan _data menunjukkan kepada anda apa yang sebenarnya ada di dalamnya. Jika anda menemui direktori pgdata atau mysql di dalamnya, berhenti dan buat salinan sebelum anda meneruskan tindakan. Pemusnahan yang sama berlaku melalui docker compose down -v, yang membuang setiap volume yang diisytiharkan oleh fail compose dan tidak meminta pengesahan anda terlebih dahulu.
Volume adalah satu-satunya perkara pada Docker host yang tidak boleh dicipta semula melalui binaan semula (rebuild). Itulah sebabnya data volume perlu berada dalam sandaran restic yang berjalan di luar pelayan, di mana flag yang tersalah taip tidak dapat mencapainya.
Apabila tiada apa-apa yang dibuang: fail log kontena
Anda telah menjalankan proses pembersihan, docker system df menunjukkan hampir tiada ruang yang boleh dituntut semula, namun cakera masih penuh. Periksa fail log.
sudo find /var/lib/docker/containers -name '*-json.log' -exec du -h {} + | sort -h | tail -10Setiap kontena menulis output standard dan ralat standardnya ke dalam fail JSON di bawah /var/lib/docker/containers/. Dalam pemasangan lalai, max-size tidak ditetapkan, yang bermaksud tiada had. Oleh itu, satu kontena yang terperangkap dalam gelung ranap akan menulis sehingga partition penuh. Tiada arahan pembersihan yang memadamkan fail ini kerana kontena yang menghasilkannya sedang berjalan, yang menjadikannya tidak boleh dibuang mengikut takrifan.
Jangan padam fail tersebut. Menjalankan rm pada fail log yang terbuka tidak akan membebaskan ruang, kerana daemon Docker masih memegang deskriptor fail yang terbuka dan kernel mengekalkan blok tersebut diperuntukkan sehingga pemegang itu ditutup. df tidak akan berubah sama sekali. Sebaliknya, lakukan pemotongan (truncate), yang mengekalkan inode yang sama dan membolehkan daemon terus menulis.
sudo find /var/lib/docker/containers -name '*-json.log' -exec truncate -s 0 {} +
df -h /Itu hanyalah penyelesaian sementara. docker logs untuk kontena tersebut kini tidak mengembalikan apa-apa, dan fail tersebut akan mula membesar semula dengan serta-merta. Penyelesaian sebenar ialah penggiliran (rotation), yang diterangkan dalam bahagian seterusnya.
Ukur sebelum dan selepas, setiap kali
Jangan meneka kesan tindakan pembersihan (prune). Ambil bacaan, jalankan satu arahan, kemudian ambil bacaan sekali lagi.
df -h /
docker system df
docker builder prune -f --filter until=168h
docker image prune -f
docker system df
df -h /Bandingkan kedua-dua output df. Itu adalah satu-satunya angka yang menentukan sama ada pelayan anda terus berfungsi. docker system df kemudian memberitahu anda baris mana yang sebenarnya berubah, dan setiap proses pembersihan mencetak angka Total reclaimed space: masing-masing.
Jika df tidak berubah tetapi docker system df menyatakan ruang telah dikosongkan, ini bermakna pemegang fail (file handle) yang terbuka masih menahan blok yang telah dipadam; ini adalah masalah fail log yang dinyatakan di atas. Jika kedua-duanya berubah tetapi cakera penuh semula dalam masa sehari, anda menghadapi masalah pertumbuhan data dan bukannya masalah pembersihan. Penyelesaiannya ialah putaran log (rotation) serta tugasan berjadual (scheduled job).
Cara mengelakkan cakera penuh semula
Hadkan saiz log. Cipta atau sunting /etc/docker/daemon.json.
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}Tetapan ini mengehadkan log setiap kontena kepada 30 MB. Setiap nilai di bawah log-opts mestilah dalam bentuk rentetan (string), termasuk nilai berangka. Pastikan fail tersebut boleh dihuraikan (parse) sebelum anda memulakan semula perkhidmatan, kerana daemon.json yang tidak lengkap akan menyebabkan daemon gagal bermula dan semua kontena akan terhenti.
python3 -m json.tool /etc/docker/daemon.json
sudo systemctl restart docker
docker info | grep -i 'logging driver'docker info sepatutnya melaporkan Logging Driver: json-file sekarang. Had tersebut akan dipaparkan dalam bahagian LogConfig bagi docker inspect untuk kontena yang dicipta selepas but semula. Ini adalah perincian penting: tetapan ini hanya terpakai kepada kontena baharu. Kontena sedia ada mengekalkan konfigurasi asal, jadi anda perlu menciptanya semula.
docker compose up -d --force-recreateHad yang sama boleh ditetapkan bagi setiap servis dalam fail compose, yang merupakan pilihan lebih baik apabila satu servis yang menghasilkan banyak log memerlukan had tersendiri.
services:
app:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"Jadualkan pembersihan (prune) secara terhad. Lakukan secara mingguan, khusus untuk imej yang tergantung (dangling) dan cache binaan lama. Jangan sesekali meletakkan -a atau --volumes dalam tugasan berjadual, kerana tugasan yang berjalan semasa stack tidak aktif akan memadamkan imej stack tersebut, dan dengan --volumes, ia akan memulakan proses pada data anda.
sudo tee /etc/cron.weekly/docker-prune >/dev/null <<'EOF'
#!/bin/sh
docker image prune -f
docker builder prune -f --filter until=168h
EOF
sudo chmod +x /etc/cron.weekly/docker-prune
sudo /etc/cron.weekly/docker-pruneBaris terakhir itu menjalankan skrip secara manual supaya anda dapat melihat outputnya sebelum ia berjalan tanpa pengawasan. Fail tersebut mestilah boleh laksana (executable), dan namanya tidak boleh mengandungi titik, kerana run-parts akan melangkau sebarang fail yang tidak boleh laksana atau yang mempunyai sambungan (extension).
Penggera ruang cakera kosong. Pembersihan yang dilakukan selepas cakera penuh hanyalah langkah pemulihan. Makluman pada 80 peratus adalah langkah pencegahan.
usage=$(df --output=pcent / | tr -dc '0-9')
[ "$usage" -ge 80 ] && echo "root filesystem at ${usage} percent full"Masukkan arahan tersebut ke dalam cron bersama sistem pemberitahuan yang anda gunakan. Ruang kosong hanyalah sebahagian daripada gambaran sebenar, jadi gabungkan penggera ini dengan pemantauan kesihatan cakera pada VPS anda, kerana cakera yang rosak dan cakera yang penuh kedua-duanya akan menghentikan kontena anda, dan kedua-duanya memerlukan penyelesaian yang berbeza.
Segala arahan di atas mengandaikan pemasangan standard dengan root data di /var/lib/docker. Jika anda telah memindahkannya menggunakan kunci data-root dalam daemon.json, gantikan laluan tersebut dalam setiap arahan. Menyediakan susun atur yang betul pada pelayan baharu adalah sebahagian daripada menyediakan Docker pada VPS, dan adalah jauh lebih mudah untuk membuat keputusan tersebut sebelum anda mempunyai 40 GB kontena yang tersimpan pada partition yang salah.
FAQ
Adakah docker system prune memadamkan volume saya?
Tidak. Perintah asas tersebut membuang kontena yang dihentikan, rangkaian yang tidak digunakan, imej yang tergantung (dangling) dan cache binaan yang tidak digunakan; gesaan pengesahan akan menyenaraikan item tersebut dengan tepat. Volume hanya akan terlibat apabila anda menambah --volumes, dan sejak Docker Engine 23.0, flag tersebut hanya meliputi volume tanpa nama (anonymous) dan bukannya volume bernama. Volume bernama hanya akan dipadamkan melalui docker volume prune -a dan docker compose down -v. Itu adalah dua perintah yang perlu anda gunakan dengan berhati-hati.
Mengapa cakera saya masih penuh selepas menjalankan docker prune?
Terdapat dua punca biasa. Pertama ialah fail log kontena di bawah /var/lib/docker/containers/, yang tidak disentuh oleh mana-mana perintah prune dan akan terus membesar tanpa had sehingga anda menetapkan max-size. Kedua ialah fail yang telah dipadamkan tetapi masih dibuka oleh sesuatu proses: jika anda memadamkan log dengan rm semasa kontena sedang berjalan, daemon akan mengekalkan deskriptor fail tersebut dan kernel tidak akan melepaskan blok storan, menyebabkan df melaporkan tiada perubahan. Bandingkan sudo du -xh --max-depth=1 /var/lib/docker dengan docker system df untuk melihat punca yang mana satu berlaku kepada anda.
Apakah perbezaan antara docker image prune dan docker image prune -a?
Perintah asas hanya membuang imej yang tergantung (dangling), iaitu imej yang kehilangan tag, biasanya disebabkan oleh proses binaan semula (rebuild). Bentuk -a pula membuang setiap imej yang tidak dirujuk oleh mana-mana kontena sedia ada, termasuk imej bertag yang anda muat turun secara sengaja. Selepas docker compose down, kontena akan hilang, jadi -a akan turut membuang imej bagi stack tersebut. Tiada apa-apa yang hilang secara kekal kerana proses permulaan seterusnya akan memuat turun atau membina semula imej tersebut, namun ia akan mengambil masa yang lama jika sambungan internet anda perlahan.
Bagaimanakah cara untuk menghalang log Docker daripada memenuhi cakera?
Tetapkan max-size dan max-file di bawah log-opts dalam /etc/docker/daemon.json, kemudian mulakan semula daemon dengan sudo systemctl restart docker. Tetapan ini hanya terpakai kepada kontena yang dicipta selepas proses mulakan semula tersebut, jadi cipta semula kontena yang sedang berjalan dengan docker compose up -d --force-recreate. Anda boleh menetapkan dua pilihan yang sama bagi setiap servis dalam fail compose di bawah kunci logging, yang disyorkan jika satu servis menghasilkan log yang jauh lebih banyak berbanding servis lain.
Adakah selamat untuk menjalankan docker system prune dalam cron job?
Perintah docker system prune -f asas adalah selamat pada hos di mana setiap stack sentiasa berjalan, namun ia akan membuang kontena yang dihentikan, jadi ia akan memadamkan kontena yang anda hentikan dengan sengaja dan bercadang untuk memulakannya semula kemudian. Tugasan berjadual yang lebih selamat ialah docker image prune -f berserta docker builder prune -f --filter until=168h, yang mengosongkan dua baris data yang paling cepat membesar dan tidak akan menyentuh volume. Jangan sesekali menjadualkan -a atau --volumes.