İçeriğe Atla
Mustafa Erbay
Teknoloji İnsan tarafından yazıldı Production Diaries · 9 dk okuma · görüntülenme Read in English
100%

Docker Bir Günde 56 GB Disk Yedi: Cleanup Otomasyonunu Kurma Hikayesi

VPS'imde disk %100 doldu, 5 saat blogum yayın atamadı. Docker build cache 33 GB, unused images 23 GB. Pruning + systemd timer ile kalıcı çözüm.

Docker Bir Günde 56 GB Disk Yedi: Cleanup Otomasyonunu Kurma Hikayesi — yaşanmış hikaye kapak görseli

“kaç saattir post yok” mesajı geldi

Akşam saatlerinde fark ettim — saatlik content-generate cron’um sabahtan beri tek başarılı çalıştırma yapamamış. Pipeline-health monitor henüz state-change mailini atmamıştı (4 saat eşik dolmamış), ama GitHub Actions paneli kıpkırmızı.

Son başarılı çalışma 2026-05-04 12:11 UTC’de bitmiş, üzerinden 5+ saat geçmiş, 0 yeni içerik. Bu blog’un en sık aşağı düşme nedeni kaynak yetersizliği — disk veya RAM. İlk hangi olduğunu hızlıca buldum.

Run log’larında dikkat çeken satır:

##[error] System.IO.IOException: No space left on device
  : '/home/github-runner/runner-mustafaerbay/_diag/pages/...log'

Runner kendi log dosyasını yazamıyor — diskte yer yok. Bu noktada validate adımına bile geçmemiş, runner’ın kendi _diag katmanı ölmüş. Cron başına tekrar tekrar deneniyor ama her seferinde aynı yerde patlıyor.

VPS’e SSH at, gör

$ ssh vps 'df -h /'
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        72G   72G   11M 100% /

72 GB diskte 11 MB serbest. Bir log satırı bile yazılamaz.

İkinci sorgu daha enteresan:

$ ssh vps 'sudo du -hx --max-depth=2 / 2>/dev/null | sort -hr | head -10'
72G  /
54G  /var
39G  /var/lib
15G  /var/www
7.2G /home
5.3G /home/github-runner
4.0G /usr
2.9G /opt
2.6G /usr/lib
2.3G /opt/mustafaerbay

/var/lib 39 GB. /var/www 15 GB. Bu bir kişisel blog VPS’i değil, üzerinde 6 farklı proje var. Gözüm /var/lib’e takıldı çünkü orada Docker var.

$ ssh vps 'sudo du -hx --max-depth=1 /var/lib | sort -hr | head'
39G  /var/lib
38G  /var/lib/docker BURASI
169M /var/lib/dkms
164M /var/lib/Acronis
140M /var/lib/apt
6.3M /var/lib/mustafaerbay

Docker tek başına 38 GB.

Docker’in iç dökümünü çıkar

$ ssh vps 'sudo docker system df'
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          33        9         27.5GB    23.27GB (84%)
Containers      13        13        1.192MB   0B (0%)
Local Volumes   8         8         387MB     0B (0%)
Build Cache     388       0         7.695GB   7.695GB

Bu tablo direkt cevap veriyor:

  • 33 image var, sadece 9 tanesi aktif. 24’ü “kullanılmıyor ama silinmemiş” durumda. 23.27 GB reclaimable.
  • 388 build cache layer’ı var, 0’ı aktif. Tamamı (7.7 GB) silinebilir.
  • Container’lar ve volume’lar normal — onları boşaltmak istemiyorum (postgres data falan var).

Toplam silinebilir: ~31 GB. Sadece bunu boşaltsam diskte yeterli yer açılır.

Önce çalışan container’ları görelim, sonra kes

Dur acele etme. docker system prune -a her şeyi siler — çalışan ile çalışmayan image arasındaki sınırı bilmek lazım. docker ps çıktısına göz attım: aynı VPS’te yarım düzine farklı projenin container’ları var — kendi yan ürünlerim ve birkaç müşteri projesi. Toplam 13 sağlıklı container: postgres’ler, redis’ler, Next.js app’leri, bir Astro SSR servisi ve birkaç worker. Reclaim edebilecekleri sadece ANCHORLU OLMAYAN image’ler — yani çalışan bir container’ın referans etmediği eski image versiyonları.

İki güvenli komut sıraladım:

# 1. Build cache (eski layer'lar, hiç birşey kullanmıyor)
sudo docker builder prune -af

# 2. Unused images (çalışan container'a anchor'lı olmayanlar)
sudo docker image prune -af

-a flag’i tag’lı ama dangling olmayan image’leri de siler. Riskli mi? Bence değil, çünkü aktif container’a anchor’lı olanlar zaten silinmez (Docker reference count tutar). Sadece “bir zamanlar build edildi, kullanıldı, sonra yeni versiyon geldi” durumundaki eski image’ler gider.

Sonuç:

=== Docker build cache ===
Total reclaimed space: 33.48GB

=== Docker unused images ===
Total reclaimed space: 22.62GB

=== After ===
/dev/sda1   72G   40G   33G  56% /

56 GB reclaim ettim. Disk %100 → %56. 33 GB serbest alan. 13 container hepsi çalışmaya devam ediyor.

Şimdi: bunu otomatik yapalım

Bu olay üçüncü kez yaşanmıyor — bana ders olsun:

“İki kez yaşandığında bir manuel düzeltme yap. Üçüncüsünde otomatize et.”

Hazırladığım disk-cleanup.sh script’i basit ama dikkatli. Birkaç prensip:

#!/usr/bin/env bash
set -euo pipefail

echo "=== disk-cleanup başlıyor ==="
echo "before: $(df -h / | tail -1)"

# 1) Docker build cache > 72h (yeni cache hayatta kalır)
echo "-- docker builder prune (>72h)"
docker builder prune -af --filter "until=72h"

# 2) Dangling docker images (no -a — tagged-but-unused KORUNUR)
echo "-- docker image prune (dangling only)"
docker image prune -f

# 3) journal > 7d
journalctl --vacuum-time=7d

# 4) APT cache (regenerable)
apt-get clean

# 5) mustafaerbay dist-old (deploy backup, regenerated each deploy)
[ -d /opt/mustafaerbay/dist-old ] && rm -rf /opt/mustafaerbay/dist-old

# 6) GitHub runner _diag log dosyaları > 14d (sadece dosya, dizinleri DOKUNMA)
find /home/github-runner -path '*/_diag/*' -type f -name '*.log' -mtime +14 -delete

echo "after:  $(df -h / | tail -1)"

Daily timer’a bağladım, 03:30 UTC’de çalışıyor:

[Timer]
OnCalendar=*-*-* 03:30:00
RandomizedDelaySec=10m
Persistent=true

RandomizedDelaySec=10m — sistemde başka 03:30 cron’ları varsa aynı anda çakışmasın diye. Persistent=true — VPS reboot ettiyse kaçırılan sefer çalışır.

Sonuç: tek satır neden?

Diskim doldu çünkü Docker zerre temizlik yapmaz. Her docker-compose build yeni bir image oluşturur, eskisini referenced bırakmaz ama silmez de. Birkaç ay sonra bir yıl sonra disk patladığında “wow yapay zeka mı bu kadar büyüdü” dersin.

Aslında kimse büyütmüyor. Docker hoarder. Aktif değilsen disk yangını sana bunu öğretiyor.

İki saatlik bir manuel kurtarma + bir saatlik systemd timer kurulumu = bir daha bunu yaşamayacağım garantisi. Asıl ders bu: incident’i sonraki seferinin altyapısı yap.

Yarın disk-cleanup.timer ilk seferini koşacak. Bekliyorum.

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Yorumlar

Sunucu Taraflı AI Moderasyon

Yorumlar sunucuda yapay zeka ile denetlenir ve kalıcı olarak saklanır.

?
0/2000

Sunucu taraflı AI denetim

✉️ Ücretsiz · Spam yok · İstediğin an çık

Haftalık özet — AI değil, bizzat ben seçiyorum

Haftada bir mail: o haftanın en önemli yazısı, perde arkası notları, ve "bu hafta gerçekten kullandığım araç" bölümü. Az gürültü, çok sinyal.

  • 📌
    Haftanın en iyisi Sadece okumaya değer tek yazı
  • 🔧
    Alet çantası Bu hafta kullandığım araçlar
  • 🧠
    Perde arkası Blog'a girmeyen notlar

Spam yapmıyoruz. İstediğiniz zaman ayrılabilirsiniz. · Sadece Umami (self-hosted, Google yok) ile takip.

Okuma İstatistikleriniz

0

Yazı Okundu

0dk

Okuma Süresi

0

Gün Serisi

-

Favori Kategori

İlgili Yazılar