7.6 GB’lık bir VPS üzerinde, bir yan ürünümün backend’ini barındırırken, Docker’ın aniden disk alanını tüketmesiyle karşılaştım. Bu durum, özellikle kısıtlı kaynaklara sahip sunucularda sıkça rastlanan ve dikkatli yönetim gerektiren bir problem. Benim için bu, sadece bir disk doluluğu uyarısından öte, sistemin stabil çalışmasını etkileyen bir kök neden analizi gerektirdi.
Bu yazıda, Docker’ın neden bu kadar yer kapladığını, kendi VPS’imde yaşadığım somut örnekler üzerinden nasıl tespit ettiğimi ve kalıcı çözümler için hangi adımları uyguladığımı detaylıca anlatacağım. Amacım, benim gibi benzer sorunlar yaşayan herkesin pratik bir yol haritası bulmasına yardımcı olmak.
Docker Neden Bu Kadar Yer Kaplar?
Docker’ın disk kullanımını anlamak, sorun gidermenin ilk adımıdır. Sıkça gözden kaçan birkaç temel neden var. Bunlar genellikle image’lar, container’lar, volume’lar ve build cache gibi bileşenlerin birikmesinden kaynaklanıyor.
Her bir bileşenin disk üzerindeki etkisini doğru anlamak, gereksiz alanı temizlemek ve gelecekteki sorunları önlemek için kritik öneme sahip. Özellikle küçük VPS’lerde bu yönetim çok daha hassas olmak zorunda.
Image Katmanları ve Disk Kullanımı
Docker image’ları katmanlar halinde oluşturulur. Bir image’ın her bir komutu (RUN, COPY, ADD) yeni bir katman oluşturur. Bu katmanlar, aynı temel image’ı kullanan farklı image’lar arasında paylaşılabilir, ancak kullanılmayan veya “dangling” (etiketsiz) kalmış katmanlar diskte yer kaplamaya devam eder.
Benim durumumda, sık sık image güncellemeleri ve testler yaptığım için eski image katmanları birikmişti. docker images komutuyla bunları görmek mümkün, ancak asıl sorun dangling image’lar ve bunların oluşturduğu katmanlarda gizliydi.
# Tüm image'ları listele, dangling olanları bul
docker images -a | grep "<none>"
# Image'ların disk kullanımını özetle
docker system df
Container Logları ve Volume Yönetimi
Container’lar çalıştıkça log üretirler ve bu loglar, varsayılan olarak diskte saklanır. Özellikle yoğun trafik alan veya hata üreten uygulamaların logları, kısa sürede gigabaytlarca yer kaplayabilir. Bu, benim VPS’imde disk doluluğuna en çok katkıda bulunan unsurlardan biriydi.
Bunun yanı sıra, Docker volume’ları da önemli bir yer tutar. Volume’lar, container’ların veri depolaması için kullanılır ve container silinse bile varsayılan olarak kalıcıdır. Kullanılmayan veya unutulmuş volume’lar, zamanla büyük bir disk yığınına dönüşebilir.
Log boyutlarını sınırlamak için docker-compose.yml dosyasında logging yapılandırmasını kullanabiliriz. Ben genellikle max-size ve max-file limitleri belirleyerek bu sorunu çözüyorum.
version: '3.8'
services:
app:
image: myapp:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Volume’ları yönetmek için ise öncelikle hangi volume’ların kullanıldığını anlamak gerekiyor. docker volume ls komutu tüm volume’ları listeler. Ardından, docker volume inspect <volume_name> ile detaylarına bakabiliriz.
# Kullanılmayan (dangling) volume'ları bul
docker volume ls -f dangling=true
# Belirli bir volume'u sil (dikkatli olun, veri kaybına yol açabilir!)
docker volume rm <volume_name>
Build Cache ve Geliştirme Ortamları
Eğer VPS üzerinde Docker image’ları build ediyorsanız, build cache de önemli bir disk tüketicisi olabilir. Docker, image katmanlarını yeniden kullanmak için build cache’i saklar. Bu, build sürelerini kısaltır ancak zamanla gereksiz cache katmanları birikmesine neden olur.
Ben kendi CI/CD pipeline’ımı self-hosted runner’lar üzerinde çalıştırırken bu durumla sıkça karşılaştım. Özellikle sık sık denemeler ve hatalı build’ler yaptığım zamanlarda build cache’in beklenenden fazla yer kapladığını gördüm.
Build cache’i temizlemek için docker builder prune komutu oldukça etkilidir. Bu komut, kullanılmayan build cache’i temizleyerek önemli miktarda disk alanı açabilir.
# Tüm kullanılmayan build cache'i temizle
docker builder prune
Gerçek Bir Olay: Kendi VPS’imdeki Durum
28 Nisan sabahı, bir yan ürünümün backend’ini host eden 7.6 GB’lık VPS’imde disk doluluk oranı %95’e çıkmıştı. promtail agent’ım üzerinden journald loglarını izlediğimde disk doluluk uyarısı düşmüştü. İlk kontrol ettiğim yer tabii ki /var/lib/docker dizini oldu.
# Docker'ın kök dizininin ne kadar yer kapladığını kontrol et
sudo du -sh /var/lib/docker
Çıktı beni şaşırtmadı: 6.5G /var/lib/docker. Kalan 1.1 GB’ın büyük kısmı işletim sistemi ve diğer küçük dosyalarla doluydu. Bu durum, hızlıca müdahale etmem gerektiğini gösteriyordu. Neyse ki, bu benim ilk tecrübem değildi. Daha önce de benzer durumlarla karşılaşmıştım.
Aşağıdaki gibi bir çıktı ile karşılaştım:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 55 12 3.2GB 2.8GB (87%)
Containers 18 6 1.5GB 1.3GB (86%)
Local Volumes 25 8 1.8GB 1.5GB (83%)
Build Cache 12 0 0B 0B
Bu çıktıya göre, image’lar, container’lar ve local volume’lar disk kullanımının ana kaynaklarıydı. Özellikle RECLAIMABLE sütunu, ne kadar yerin geri kazanılabileceğini açıkça gösteriyordu. Build Cache kısmının 0B olması, o an için build işlemi yapmadığımı gösteriyordu.
Adım Adım Temizleme ve Optimizasyon
Durumu analiz ettikten sonra, adım adım temizleme işlemine başladım. Amacım, mümkün olan en fazla disk alanını geri kazanmaktı. İlk olarak, kullanılmayan tüm Docker kaynaklarını temizleyen genel bir komutla başladım.
# Tüm dangling image'ları, durmuş container'ları, kullanılmayan ağları ve build cache'i temizle
docker system prune
# Tüm kullanılmayan Docker kaynaklarını temizle, buna dangling olmayan image'lar da dahil
# DİKKAT: Bu komut, aktif olarak kullanılmayan ancak bir isimle etiketlenmiş image'ları da silebilir.
# Bu yüzden dikkatli kullanılmalı ve neyin silindiğinden emin olunmalıdır.
# Ben genellikle test ortamlarında veya disk alanı krizi anında kullanırım.
docker system prune -a
docker system prune -a komutuyla 2.5 GB kadar bir alanı geri kazandım. Ancak bu yeterli değildi. Özellikle eski loglar ve bazı volume’lar hala yer kaplıyordu. Logları temizlemek için çalışan container’ların loglarını manuel olarak temizleyebilir veya log rotasyonunu ayarlayabilirdim.
Çalışan bir container’ın loglarını sıfırlamak için: