Bir docker volume, container silinse, yeniden oluşturulsa ya da imaj güncellense bile verinizin hayatta kalmasını sağlayan kalıcı depolama birimidir. Docker'da container'lar tasarım gereği geçicidir: docker rm ile bir container'ı kaldırdığınızda, onun yazılabilir katmanındaki her şey de gider. Veritabanı dosyaları, yüklenen görseller veya uygulama logları bu katmanda durduğunda tek bir docker compose down komutu saatlerce biriken veriyi siler. Volume'lar tam da bu sorunu çözmek için vardır.
Neden container içine veri yazmak risklidir?
Bir Docker imajı, üst üste binmiş salt-okunur katmanlardan oluşur. Container çalıştığında bunların üzerine ince bir yazılabilir katman eklenir ve tüm değişiklikler oraya yazılır. Bu katman container'ın ömrüne bağlıdır; container yok olduğunda katman da yok olur. Sonuç olarak:
- Container'ı yeniden oluşturmak (imaj güncellemesi, ayar değişikliği) veriyi siler.
- Yazılabilir katman üzerinden disk erişimi, doğrudan diske yazmaya göre daha yavaştır.
- Veriyi container dışından yedeklemek veya başka bir container ile paylaşmak zorlaşır.
Kalıcı olması gereken her şey container dosya sisteminin dışında, Docker'ın yönettiği bir alanda durmalıdır. İşte o alan bir volume'dur.
Volume, bind mount ve tmpfs farkı
Docker üç tür mount sunar ve hangisini seçeceğinizi bilmek önemlidir:
- Volume: Docker tarafından host üzerinde
/var/lib/docker/volumes/altında yönetilir. Taşınabilir, yedeklenebilir ve üretim için önerilen yöntemdir. - Bind mount: Host üzerindeki belirli bir klasörü (
/home/user/projegibi) doğrudan container'a bağlar. Geliştirme sırasında kodu canlı düzenlemek için idealdir, ama host yapısına sıkı bağımlıdır. - tmpfs: Veriyi yalnızca RAM'de tutar; container durunca silinir. Geçici, hassas veriler için kullanılır.
Basit kural: verinin Docker'a ait olmasını istiyorsanız volume, host'taki gerçek bir dizine bağlamak istiyorsanız bind mount kullanın.
Volume oluşturma ve kullanma
Adlandırılmış (named) bir volume oluşturup bir container'a bağlamak en yaygın senaryodur:
docker volume create db_data
docker run -d \
--name postgres \
-v db_data:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=gizli \
postgres:16
Buradaki -v db_data:/var/lib/postgresql/data ifadesi şunu söyler: db_data adlı volume'u, container içindeki PostgreSQL veri dizinine bağla. Container'ı silip aynı volume ile yeniden başlattığınızda veritabanı olduğu yerde durur. Mevcut volume'ları görmek için:
docker volume ls
docker volume inspect db_data
Compose ile kalıcı veri
Gerçek projelerde volume'ları genelde docker-compose.yml içinde tanımlarsınız. Aşağıdaki örnek bir veritabanını kalıcı bir volume ile çalıştırır:
services:
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: gizli
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
Burada en alttaki volumes: bloğu adlandırılmış volume'u tanımlar, servis içindeki satır ise onu bağlar. docker compose down çalıştırdığınızda container'lar silinir ama mysql_data volume'u kalır; docker compose up dediğinizde veri geri gelir. Volume'u da silmek isterseniz bilinçli olarak docker compose down -v dersiniz.
Volume yedekleme ve geri yükleme
Volume'lar host dosya sisteminde gömülü durduğu için yedeklemenin temiz yolu, geçici bir yardımcı container ile içeriği bir arşive almaktır:
# Yedek al: db_data volume'unu tar.gz olarak kaydet
docker run --rm \
-v db_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/db_data.tar.gz -C /data .
# Geri yükle: arşivi boş bir volume'a aç
docker run --rm \
-v db_data:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/db_data.tar.gz -C /data
Bu yöntem küçük bir alpine container'ını volume'a ve mevcut dizine bağlayıp tar ile sıkıştırır. Veritabanları için ek olarak mysqldump ya da pg_dump gibi mantıksal yedekler almak, bozulmaya karşı daha güvenli bir ikinci katman sağlar.
Sık yapılan hatalar
- Yanlış yol bağlamak: Volume'u uygulamanın gerçekten veri yazdığı dizine bağlamazsanız (örneğin PostgreSQL'de
/var/lib/postgresql/data) hiçbir şey kalıcı olmaz. - İzin sorunları: Container'daki kullanıcı kimliği ile volume'daki dosya sahibi uyuşmazsa "permission denied" hataları görürsünüz.
- Anonim volume biriktirmek: Ada bağlamadan oluşan anonim volume'lar zamanla diski doldurur;
docker volume pruneile temizleyin (dikkatli olun).
Sık Sorulan Sorular
Volume ile bind mount arasında hangisini seçmeliyim?
Üretim ortamında, verinin taşınabilir ve Docker tarafından yönetilen olmasını istediğinizde volume seçin. Geliştirme sırasında host'taki kodu canlı düzenlemek isterseniz bind mount daha pratiktir.
Container'ı silersem volume de silinir mi?
Hayır. Adlandırılmış volume'lar container'dan bağımsızdır ve docker rm ile silinmez. Yalnızca docker volume rm ya da docker compose down -v gibi açık bir komut volume'u kaldırır.
Aynı volume'u birden çok container paylaşabilir mi?
Evet, aynı volume'u birden fazla container'a bağlayabilirsiniz. Ancak veritabanları gibi tek yazıcı bekleyen servislerde aynı volume'a paralel yazmak bozulmaya yol açabilir; bunu dikkatli planlayın.
Verinizi container'ın insafına bırakmayın. Docker volume stratejisi, yedekleme veya container altyapısı kurulumunda desteğe ihtiyacınız varsa benimle iletişime geçin.