Docker bind mount, host makinedeki bir dosyayı ya da dizini olduğu gibi container içine bağlar. Volume'dan farkı, verinin Docker'ın kendi depolama dizininde değil, sizin seçtiğiniz bir host yolunda durması ve hem host üzerindeki süreçlerin hem de container'ın aynı dosyaları aynı anda değiştirebilmesidir. Bir yapılandırma dosyasını sunucuda düzenleyip container'ın görmesini istiyorsanız, ya da container'ın ürettiği dosyaların doğrudan host dosya sisteminde durmasını istiyorsanız bind mount doğru araçtır.
Bu yazıda bind mount'u bir Linux sunucu açısından ayrıntılı olarak ele alıyoruz: -v ile --mount arasındaki davranış farkı (özellikle kaynak dizin yokken), salt okunur bağlama, dolu bir dizinin üstüne bağlama, özyinelemeli bağlamalar, bind propagation, SELinux etiketleri ve Compose içindeki kısa ve uzun sözdizimi. Volume ile bind mount arasındaki temel seçim Docker Compose başlangıç rehberi yazısında özetleniyor; volume'un kendisi ise Docker volume kullanımı yazısında.
Bind mount ne zaman kullanılır?
Belgeler bind mount için üç tipik kullanım sayıyor. Birincisi, geliştirme ortamındaki kaynak kodu ya da derleme çıktılarını container ile paylaşmak. İkincisi, container içinde dosya oluşturup bu dosyaların host dosya sisteminde kalıcı olmasını istemek. Üçüncüsü, host üzerindeki yapılandırma dosyalarını container'lara vermek. Docker'ın kendisi de bu son yöntemi kullanır: container'lara varsayılan DNS çözümlemesini, host'taki /etc/resolv.conf dosyasını her container'a bağlayarak sağlar.
Bind mount yalnızca çalışan container'lar için değildir; build sırasında da kaynak kodu build container'ına bağlayıp test, lint ya da derleme yapabilirsiniz. Build tarafındaki bu kullanımı ve COPY ile farkını Docker COPY ve ADD farkı yazısı ele alıyor. Bu yazıdaki her şey çalışan container'lardaki bind mount ile ilgilidir.
Bir sunucuda bind mount'un en sık görüldüğü yerler web sunucusu yapılandırmaları, statik site dosyaları, sertifika dizinleri ve uygulamanın yüklenen dosyaları yazdığı dizinlerdir. Veritabanı dizinleri gibi yoğun yazılan ve host tarafında elle dokunulmaması gereken veriler için ise belgeler volume'u öneriyor; volume'lar Docker CLI ile yönetilebilir ve yedeklemesi daha kolaydır.
Kısıtlar ve güvenlik etkileri

Bind mount'un esnekliği bazı sorumlulukları da beraberinde getirir. Belgeler üç konuyu özellikle vurguluyor:
- Varsayılan olarak yazma erişimi vardır. Container içindeki süreçler host dosya sistemini değiştirebilir; önemli sistem dosyalarını oluşturabilir, değiştirebilir ya da silebilir. Bu, host üzerindeki Docker dışı süreçleri de etkileyebilecek bir güvenlik konusudur. Container'ın yazmasına gerek yoksa
readonlyya daroseçeneğini kullanın. - Bağlama daemon'ın çalıştığı host'ta yapılır, istemcide değil. Uzak bir Docker daemon'ına bağlıysanız istemci makinenizdeki dosyaları container'a bind mount ile veremezsiniz. Docker Desktop'ta daemon bir Linux sanal makinesinde çalışır ve Desktop bunu kendi mekanizmalarıyla şeffaf biçimde çözer.
- Container host'a sıkı bağlıdır. Bind mount, host dosya sisteminde belirli bir dizin yapısının bulunmasına dayanır. Aynı dizin yapısı olmayan başka bir host'ta container başarısız olabilir.
İkinci madde, sunucuyu dizüstü bilgisayarınızdan yönetiyorsanız önemlidir. docker context ile uzak bir sunucuya bağlanıp -v ./site:/usr/share/nginx/html yazdığınızda kaynak yol sizin bilgisayarınızda değil sunucuda aranır. Uzak engine yönetimi için Docker context ile uzak sunucu yönetimi yazısına bakabilirsiniz.
-v ve --mount sözdizimi, kaynak yokken davranış
Bind mount oluşturmak için de --mount ya da --volume (-v) kullanılır. Belgeler genel olarak --mount öneriyor, çünkü daha açık ve tüm seçenekleri destekliyor.
docker run --mount type=bind,src=<host-path>,dst=<container-path>
docker run --volume <host-path>:<container-path>İki bayrak arasındaki en önemli pratik fark, host'taki kaynak yol yokken ortaya çıkar. -v ile henüz var olmayan bir yolu bağlarsanız Docker bu yolu host üzerinde sizin için oluşturur ve her zaman dizin olarak oluşturur. Bu, bir dosyayı bağlamak isterken yazım hatası yaptığınızda host'ta o adda boş bir dizin oluşması ve container'ın yapılandırma dosyası yerine bir dizin görmesi demektir. Daemon'ın kaynak dizini oluşturma izni yoksa dizini container'ı başlatmadan önce kendiniz oluşturmalısınız.
--mount ise varsayılan olarak kaynak yolu oluşturmaz ve hata verir. Belgelerdeki örnek çıktı şöyledir:
docker run --mount type=bind,src=/dev/noexist,dst=/mnt/foo alpine
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /dev/noexist.Kaynak dizinin yoksa oluşturulmasını istiyorsanız bind-create-src seçeneğini ekleyebilirsiniz. Engine 29 sürüm notlarına göre bu seçenek 29.3.0 sürümünde --mount bayrağına eklendi; bu yüzden daha eski bir CLI ile çalışmayabilir.
docker run --mount type=bind,src=/home/user/mydir,dst=/mnt/foo,bind-create-src alpineSunucuda hata vermesini tercih etmeniz genellikle daha güvenlidir: yanlış yazılmış bir yol sessizce boş bir dizin üretmek yerine container'ın başlamamasına yol açar ve hatayı hemen görürsünüz. --mount için geçerli seçenekler şunlardır:
| --mount seçeneği | Anlamı |
|---|---|
| source, src | Host'taki dosya veya dizin; mutlak ya da göreli yol olabilir |
| destination, dst, target | Container içindeki yol; mutlak olmalı |
| readonly, ro | Salt okunur bağlar |
| bind-propagation | Bind propagation ayarını değiştirir |
| bind-create-src | Kaynak dizin yoksa host üzerinde oluşturur |
| bind-recursive | Alt bağlamaların nasıl ele alınacağını belirler (yalnızca --mount) |
-v tarafında üçüncü alan virgülle ayrılmış seçenek listesidir: ro (readonly), SELinux için z ve Z, propagation için de rprivate (varsayılan), private, rshared, shared, rslave ve slave. Belgelerdeki iki örnek aynı bağlamayı iki sözdizimiyle yazar:
docker run --mount type=bind,src=.,dst=/project,ro,bind-propagation=rshared
docker run -v .:/project:ro,rsharedBind mount ile container başlatmak
Belgelerdeki senaryoda source adlı bir proje dizini var ve derleme çıktıları source/target/ altına yazılıyor. Amaç, her derlemede container'ın yeni çıktıyı /app altında görmesi. Komut source dizininin içinden çalıştırılır; $(pwd) Linux ve macOS'ta o anki çalışma dizinine genişler:
docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
nginx:latestdocker inspect devtest çıktısının Mounts bölümünde türün bind olduğunu, kaynak ve hedef yolları, bağlamanın okuma yazma olduğunu ve propagation değerinin rprivate olduğunu görürsünüz. Belgelerdeki çıktı:
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/source/target",
"Destination": "/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],Volume çıktısından farklı olarak burada Name ve Driver alanları yoktur, çünkü bind mount Docker'ın yönettiği bir nesne değildir. docker volume ls bind mount'ları listelemez ve docker volume prune onlara dokunmaz; host'taki dizinin yaşam döngüsü tamamen sizin sorumluluğunuzdadır.
Dolu bir dizinin üstüne bağlamak
Container içinde dosya bulunan bir dizine bind mount yaparsanız dizinin mevcut içeriği bağlama tarafından örtülür. Bu, imajı yeniden derlemeden uygulamanın yeni bir sürümünü denemek için faydalı olabilir, ama aynı zamanda şaşırtıcı da olabilir. Belgeler özellikle bu davranışın volume'lardan farklı olduğunu belirtiyor: boş bir volume bağlandığında container içindeki dosyalar volume'a kopyalanır, bind mount'ta ise böyle bir kopyalama yoktur; host dizini boşsa container o dizini boş görür.
Belgelerdeki uç örnek, container'ın /usr dizinini host'taki /tmp ile değiştirir. Nginx'in çalıştırılabilir dosyası artık görünmediği için container oluşturulur ama başlamaz:
docker run -d \
-it \
--name broken-container \
--mount type=bind,source=/tmp,target=/usr \
nginx:latest
docker: Error response from daemon: oci runtime error: container_linux.go:262:
starting container process caused "exec: \"nginx\": executable file not found in $PATH".Gerçek hayatta bu genellikle daha masum bir biçimde olur: bir web sunucusu imajının içerik dizinine boş bir host dizini bağlarsınız ve varsayılan sayfa yerine boş bir dizin listesi ya da hata görürsünüz. Bağlamayı kaldırıp örtülen dosyaları yeniden göstermenin kolay bir yolu yoktur; en iyi seçenek container'ı bağlama olmadan yeniden oluşturmaktır.
Salt okunur bind mount
Bazı geliştirme senaryolarında container'ın bind mount'a yazması ve değişikliklerin host'a geri yansıması istenir. Sunucuda ise çoğu zaman yalnızca okuma erişimi yeterlidir. Salt okunur bağlama için --mount tarafında readonly, -v tarafında :ro eklersiniz:
docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app:ro \
nginx:latestBu durumda docker inspect çıktısında "Mode": "ro" ve "RW": false görünür. Container'ı kaldırmak için belgeler docker container rm -fv devtest komutunu kullanıyor.
Özyinelemeli bağlamalar: bind-recursive

İçinde başka bağlamalar bulunan bir yolu bind mount ile bağlarsanız bu alt bağlamalar da varsayılan olarak bağlamaya dahil edilir. Bağlama salt okunursa Docker Engine alt bağlamaları da salt okunur yapmak için elinden geleni yapar; buna özyinelemeli salt okunur bağlama denir. Bu özellik Linux çekirdeği 5.12 veya üstünü gerektirir. Daha eski çekirdeklerde alt bağlamalar varsayılan olarak okuma yazma bağlanır ve bind-recursive=readonly ile salt okunur yapmaya çalışmak hata verir. Bu davranış yalnızca --mount ile ayarlanabilir:
| bind-recursive değeri | Davranış |
|---|---|
| enabled (varsayılan) | Çekirdek 5.12 veya üstündeyse salt okunur bağlama özyinelemeli salt okunur olur, değilse alt bağlamalar okuma yazmadır |
| disabled | Alt bağlamalar yok sayılır, bağlamaya dahil edilmez |
| writable | Alt bağlamalar okuma yazmadır |
| readonly | Alt bağlamalar salt okunurdur; çekirdek 5.12 veya üstü gerekir |
Bu konu özellikle bir dizini salt okunur bağladığınız halde altındaki bir bağlama noktasına yazılabildiğini fark ettiğinizde önem kazanır. Eski bir çekirdekte çalışan sunucularda salt okunur bağlamanın alt bağlamaları kapsamayabileceğini aklınızda tutun. Ayrıca Engine 29.0.0 sürüm notları, artık kullanımdan kaldırılmış olan bind-nonrecursive seçeneğinin --mount bayrağından çıkarıldığını kaydediyor; eski betiklerinizde bu seçenek varsa bind-recursive=disabled ile değiştirmeniz gerekir.
Bind propagation

Bind propagation, bir bind mount içinde oluşturulan bağlamaların o bağlamanın kopyalarına yansıyıp yansımayacağını belirler. Varsayılan hem bind mount hem volume için rprivate'tir; yalnızca bind mount'larda ve yalnızca Linux host'larda değiştirilebilir. Belgeler bunun ileri düzey bir konu olduğunu ve çoğu kullanıcının hiç ayarlamaya ihtiyaç duymadığını belirtiyor. Docker Desktop'ta mount propagation çalışmaz.
| Ayar | Anlamı |
|---|---|
| shared | Orijinal bağlamanın alt bağlamaları kopyalara, kopyalarınkiler de orijinale yansır |
| slave | Tek yönlü: orijinaldeki alt bağlama kopyada görünür, kopyadaki orijinalde görünmez |
| private | Hiçbir yönde yansıma olmaz |
| rshared | shared gibi, iç içe bağlama noktalarını da kapsar |
| rslave | slave gibi, iç içe bağlama noktalarını da kapsar |
| rprivate | Varsayılan; iç içe noktalar dahil hiçbir yönde yansıma olmaz |
Propagation ayarlamadan önce host dosya sisteminin bunu desteklemesi gerekir. Belgelerdeki örnek aynı target/ dizinini iki kez bağlar; ikinci bağlama hem salt okunur hem rslave'dir. Bu durumda /app/foo/ oluşturduğunuzda /app2/foo/ da görünür:
docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
--mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave \
nginx:latestSELinux etiketi: z ve Z
SELinux kullanan dağıtımlarda bind mount'a z ya da Z seçeneği ekleyerek bağlanan host dosyasının veya dizininin SELinux etiketini değiştirebilirsiniz. z, içeriğin birden fazla container arasında paylaşıldığını; Z ise içeriğin özel ve paylaşılmayan olduğunu belirtir. Bu seçenekler host'taki dosyanın kendisini etkiler ve Docker'ın kapsamı dışında sonuçlar doğurabilir.
docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app:z \
nginx:latestCompose içinde bind mount
Compose'da servis volumes alanındaki kısa sözdiziminde ilk alan bir host yolu ise bağlama bind mount olur. Adlandırılmış volume ile karışmaması için göreli yollar her zaman . ya da .. ile başlamalıdır; göreli yol Compose dosyasının bulunduğu dizine göre çözülür. Erişim modu alanında rw (varsayılan), ro, z ve Z kullanılabilir; SELinux seçenekleri SELinux olmayan platformlarda yok sayılır.
services:
web:
image: nginx:latest
volumes:
- ./site:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
Bu dosyayı docker compose config ile doğruladığımızda, Compose kısa sözdizimini uzun biçime çevirdi: her satır type: bind, göreli kaynak yerine Compose dosyasının klasörüne göre çözülmüş mutlak bir yol ve read_only: true olarak yazıldı. Göreli yolların bu şekilde çözülmesi, belgelerin belirttiği gibi yalnızca yerel bir container çalışma ortamına dağıtım yapan Compose için desteklenir.
Kısa sözdizimiyle ilgili kritik bir ayrıntı daha var: belgelere göre kısa sözdizimi, host'taki kaynak yol yoksa orada bir dizin oluşturur. Bu, eski docker-compose ile geriye dönük uyumluluk için korunan bir davranıştır ve -v bayrağındaki sorunun aynısını doğurur. Örneğin ./nginx.conf dosyası henüz yokken servisi başlatırsanız host'ta nginx.conf adlı boş bir dizin oluşabilir. Bunu önlemek için uzun sözdiziminde create_host_path: false kullanın:
services:
web:
image: nginx:latest
volumes:
- type: bind
source: ./site
target: /usr/share/nginx/html
read_only: true
bind:
create_host_path: false
- type: bind
source: ./uploads
target: /data/uploads
bind:
selinux: z
Uzun sözdizimindeki bind alt alanı üç ayar kabul eder: propagation, varsayılanı true olan create_host_path ve z ya da Z değeri alan selinux. read_only ise bağlamayı salt okunur yapar. Bu dosya da doğrulamadan geçti ve config çıktısında create_host_path: false ve selinux: z ayarları korunmuş olarak göründü.
Compose'da bir host yolunu volume gibi adlandırmak isterseniz local sürücünün driver_opts alanıyla kurulan bir desen de vardır. Bu "adlandırılmış bind mount" deseni Docker volume yedekleme ve taşıma yazısında örnekleniyor.
Sık yapılan hatalar
- Dosya yerine dizin oluşması:
-vya da Compose kısa sözdizimiyle var olmayan bir dosya yolunu bağlarsanız host'ta dizin oluşur. Dosyayı önceden oluşturun ya da--mountveyacreate_host_path: falsekullanın. - Boş host dizininin imaj içeriğini örtmesi: Bind mount, volume gibi kopyalama yapmaz. Boş bir dizini içerik dizinine bağlarsanız container boş görür.
- Uzak daemon'da yerel yol beklemek: Kaynak yol daemon'ın çalıştığı host'ta aranır.
- Yazılabilir sistem dizini bağlamak: Container host dosyalarını değiştirebilir; gerekmeyen her yerde
rokullanın. - Z seçeneğini geniş dizinlerde kullanmak: Sistem dizinlerinde
Zhost'u kullanılamaz hale getirebilir. - Göreli yolu nokta olmadan yazmak: Compose'da
site:/usr/share/nginx/htmlbir named volume olarak yorumlanır; bind mount için./siteyazın.
Sık Sorulan Sorular
Bind mount mı volume mü kullanmalıyım?
Dosyalara host tarafından da erişmeniz ya da düzenlemeniz gerekiyorsa bind mount, verinin Docker tarafından yönetilmesi, kolay yedeklenmesi ve host dizin yapısından bağımsız olması gerekiyorsa volume kullanın. Belgeler kalıcı uygulama verisi için volume'u tercih edilen mekanizma olarak tanımlıyor.
Bind mount'ta dosya izinleri neden sorun çıkarıyor?
Bind mount host dosyasını olduğu gibi bağladığı için dosyanın host'taki sahibi ve izinleri container içinde de geçerlidir. Container'daki süreç farklı bir kullanıcıyla çalışıyorsa yazma izni olmayabilir. Kullanıcı ve grup yönetimi için Linux kullanıcı ve grup yönetimi yazısına bakabilirsiniz.
Tek bir dosyayı bind mount ile bağlayabilir miyim?
Evet, kaynak ve hedef bir dosya olabilir; belgelerdeki Compose örneği de bir soket dosyasını bağlıyor. Dosyanın host'ta önceden var olduğundan emin olun, aksi halde -v veya kısa sözdizimi o yolda bir dizin oluşturur.
Swarm servislerinde bind mount kullanabilir miyim?
Kullanılabilir, ancak belgelere göre servislerde SELinux etiketleri ve :ro yok sayılır. Ayrıca bind mount host dizin yapısına bağlı olduğundan, görevin çalıştığı her düğümde aynı yolun bulunması gerekir. Swarm için Docker stack deploy yazısına bakın.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Docker öğrenme rehberi · Docker volume kullanımı · tmpfs ve image mount · Volume yedekleme ve taşıma · Docker context · Docker Compose başlangıç rehberi