SSD Nodes Learn Hosting plans →
Mwongozo Matt ConnorNa Matt Connor · Imeboreshwa 2026-08-31

Bind mount vs named volume: Ipi bora kwa Docker Compose?

Jifunze tofauti kati ya bind mount na named volume katika Docker Compose. Pata mwongozo wa kuchagua kati ya faili za usanidi na data ya database ili kuepuka makosa ya ruhusa.

Bind mount au named volume: jibu fupi

Docker Compose volumes zipo za aina mbili, na chaguo hutegemea nani anayemiliki faili hizo. Tumia bind mount kwa faili unazozisoma na kuzihariri mwenyewe, kama vile configuration, templates, na tovuti tuli. Tumia named volume kwa data inayomilikiwa na programu, kama vile faili za database, search indexes, na media zilizopakiwa. Bind mount huelekeza kwenye njia (path) ya seva pangishi (host) ambayo unaweza kuifungua kwa kihariri. Named volume ni hifadhi ambayo Docker inakuundia na kuisimamia, na unaifikia kupitia Docker.

Zote huonekana chini ya ufunguo uleule wa volumes: ndani ya service, ndiyo maana watu huchanganya matumizi yake. Tofauti iko upande wa kushoto wa koloni. Upande wa kushoto unaoanza na . au / ni njia ya kwenye seva pangishi, kwa hiyo huo ni bind mount. Kitu kingine chochote ni jina, kwa hiyo huo ni named volume, na jina hilo lazima litangazwe pia kwenye block ya ngazi ya juu ya volumes:.

Sintaksia mbili katika faili la compose

services:
  db:
    image: postgres:17
    environment:
      POSTGRES_PASSWORD: changeme
    volumes:
      - pgdata:/var/lib/postgresql/data
  web:
    image: nginx:1.27
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./site:/usr/share/nginx/html:ro

volumes:
  pgdata:

pgdata:/var/lib/postgresql/data ni volume yenye jina. ./nginx.conf:/etc/nginx/nginx.conf ni bind mount, na :ro huipandisha (mount) ikiwa na ruhusa ya kusoma pekee, ambayo ndiyo chaguo-msingi sahihi kwa usanidi ambao container haipaswi kuubadilisha. Sahau sehemu ya volumes: katika ngazi ya juu na Compose itasimama na kutoa service "db" refers to undefined volume pgdata.

Iwashe huduma hiyo na uorodheshe kile ambacho Docker imekitengeneza:

docker compose up -d
docker volume ls

Volume hiyo haijaitwa pgdata. Inaitwa <project>_pgdata, ambapo jina la mradi huwa ni jina la saraka (directory) iliyohifadhi faili la compose. Saraka inayoitwa myapp inatoa myapp_pgdata. Hili ni muhimu kwa sababu kubadilisha jina la saraka kutakupa volume mpya tupu, na programu itaonekana kama imepoteza data zake. Haikupoteza: volume ya zamani bado imeorodheshwa na docker volume ls. Funga jina hilo kwa kutumia name: ndani ya faili la compose, au weka COMPOSE_PROJECT_NAME, ikiwa saraka hiyo inaweza kuhama. Mipangilio kama hiyo inapaswa kuwekwa pamoja na faili za mazingira na siri za Compose.

Kwa nini makosa ya ruhusa huathiri bind mounts pekee

Hii ndiyo tofauti kubwa zaidi ya kiutendaji, na inatokana na kanuni moja: named volume ambayo haina kitu mwanzoni inajazwa data kutoka kwenye image, lakini bind mount haifanyi hivyo kamwe.

Wakati Docker inapoweka named volume tupu juu ya saraka (directory) ambayo tayari ina maudhui kwenye image, inanakili maudhui hayo kwenye volume, ikiwa na umiliki na ruhusa zilizowekwa na image hiyo. Image rasmi ya Postgres inakuja na /var/lib/postgresql/data inayomilikiwa na mtumiaji wake wa postgres, kwa hivyo volume hiyo inamilikiwa na kitambulisho (numeric id) hicho hicho, na database inaanza kufanya kazi.

Bind mount hufanya kinyume chake. Chochote kilichopo kwenye host ndicho kinachoonekana na container, ikiwemo umiliki, na maudhui ya image kwenye njia hiyo hufichwa. Ikiwa saraka ya host haipo, Docker daemon inaiunda, na kwa vile daemon inaendeshwa kama root, utapata saraka inayomilikiwa na root:root. Mchakato wa container unaoendeshwa kama mtumiaji asiye root hautaweza kuandika kwenye saraka hiyo:

PermissionError: [Errno 13] Permission denied: '/data/app.db'

Suluhisho ni kufanya namba hizo zilingane. Umiliki kwenye bind mount hulinganishwa kwa kutumia numeric user id, si kwa jina, kwa sababu container ina /etc/passwd yake yenyewe. Mtumiaji anayeitwa app ndani ya container hana maana yoyote kwenye host. Uid 1000 inamaanisha uid 1000 pande zote mbili.

id -u
mkdir -p ./data
docker compose exec web id
sudo chown -R 1000:1000 ./data

docker compose exec web id huchapisha uid ambayo mchakato wa container unaendeshwa nayo. Linganisha saraka ya host na namba hiyo, au funga (pin) container kwenye namba yako kwa kutumia user: "1000:1000" katika huduma hiyo. Kufunga user: ni njia safi zaidi kwa programu uliyoiandika wewe mwenyewe. Kubadilisha umiliki (chowning) wa saraka ya host ni salama zaidi kwa image ambayo hukuandika wewe, kwa sababu baadhi ya images huanzisha entrypoint kama root, hupunguza mamlaka, na kutarajia umiliki maalum chini yake.

Kuna mitego mingine miwili unayopaswa kuijua. Kwenye Fedora, RHEL na mifumo mingine yenye SELinux (security-enhanced Linux) inayotekelezwa, bind mount hukataliwa hadi itakapopewa lebo mpya, kwa hivyo ongeza :z kwa njia inayoshirikiwa kati ya containers au :Z kwa njia ambayo container moja tu inapaswa kuitumia, iliyoandikwa kama - ./data:/data:Z. Na bind mount ya faili moja, badala ya saraka, huharibika wakati kihariri (editor) kinapobadilisha faili badala ya kuandika kwenye faili ile ile, kwa sababu mount hufuata inode ya asili. Container itaendelea kuona maudhui ya zamani hadi utakapoiwasha upya. Mount saraka kuu (parent directory) ikiwa faili inahaririwa mara kwa mara.

Utendaji: pale ambapo tofauti ni ya kweli

Kwenye seva ya Linux, aina zote mbili hupitia njia ile ile ya kernel, kwa hivyo tofauti ya throughput ni ndogo kiasi kwamba hupaswi kuchagua kwa msingi huo. Named volumes zinazotumia driver ya default ya local huishi kwenye filesystem ile ile kama sehemu nyingine ya Docker, chini ya /var/lib/docker/volumes/, na bind mount huishi popote ulipoelekeza.

Tofauti huonekana kwenye Docker Desktop kwa macOS na Windows, ambapo containers huendeshwa ndani ya virtual machine. Bind mount huko huvuka kutoka filesystem ya host kuingia kwenye virtual machine hiyo kupitia safu ya kushiriki faili (file sharing layer), na workloads zenye operesheni nyingi ndogo za faili, kama vile Node.js dependency tree au cache ya PHP framework, hupungua kasi kwa kiasi kinachoonekana. Named volumes hubaki ndani ya virtual machine na hazilipi gharama hiyo. Hii ndiyo sababu compose files nyingi za maendeleo hufanya bind-mount ya source directory lakini hutangaza named volume juu ya node_modules.

Tofauti nyingine ya kweli ni mahali ambapo bytes hutua. Bind mount kwenda /mnt/backup huweka data kwenye diski hiyo. Named volume hutua kwenye filesystem yoyote inayoshikilia /var/lib/docker, ambayo kwenye VPS kwa kawaida ni root disk. Database inayokua ndani ya named volume hujaza diski ile ile ambayo system logs zako zipo. Iangalie kabla haijawa tukio:

docker system df -v
df -h /var/lib/docker

docker system df -v huorodhesha kila volume pamoja na ukubwa wake, na huashiria zile ambazo hakuna container inayozirejelea tena.

Kukagua named volume

Named volume si kisanduku cheusi. Iulize Docker mahali ilipo:

docker volume inspect myapp_pgdata

Sehemu ya Mountpoint inatoa njia halisi ya host, kwa kawaida /var/lib/docker/volumes/myapp_pgdata/_data. Unaweza kuisoma kwa kutumia sudo ls, na hiyo ni muhimu kwa ukaguzi wa haraka. Usiichukulie kama mahali pa kuhariri faili. Kuandika hapo ukiwa root kunarejesha tatizo la umiliki lililoelezwa hapo juu, na njia hiyo ni maelezo ya dereva wa local ambayo madereva wengine wa volume hawashiriki.

Njia salama ya kuangalia ndani ni kutumia container ya muda inayopachika (mount) volume hiyo:

docker run --rm -v myapp_pgdata:/vol alpine ls -la /vol

Hiyo inafanya kazi kwa dereva yeyote, inaona ruhusa zilezile ambazo container halisi inaona, na haiachi kitu chochote nyuma kwa sababu ya --rm.

Kuhifadhi nakala za kila aina

Bind mount ni saraka ya kawaida, kwa hivyo zana yoyote ya kuhifadhi nakala za faili inaweza kuishughulikia. Elekeza hifadhi hiyo kwenye njia ya host na umemaliza. Named volume inahitaji hatua moja ya ziada, kwa sababu zana hiyo lazima iingie ndani yake. Mount volume hiyo na saraka ya host kwenye container ya muda mfupi, kisha andika archive:

docker run --rm \
  -v myapp_pgdata:/data:ro \
  -v "$PWD":/backup \
  alpine tar czf /backup/pgdata.tar.gz -C /data .

Rejesha kwa kubadilisha mchakato huo kwenye volume mpya:

docker volume create myapp_pgdata_restored
docker run --rm \
  -v myapp_pgdata_restored:/data \
  -v "$PWD":/backup \
  alpine tar xzf /backup/pgdata.tar.gz -C /data

tar huhifadhi umiliki wa nambari (numeric ownership) inapoendeshwa kama root ndani ya container, jambo ambalo hufanya volume iliyorejeshwa iweze kutumiwa na programu.

Onyo moja linahusu aina zote mbili. Kunakili faili za database wakati database inaendeshwa hukupa archive ya data inayobadilika, na inaweza kurejeshwa ikiwa katika hali ya uharibifu. Simamisha huduma kwanza, au fanya dump kupitia zana ya database yenyewe, kama ilivyo katika docker compose exec -T db pg_dump -U postgres appdb > appdb.sql. Hiyo hutengeneza faili ya kawaida ambayo unaweza kuiingiza kwenye utaratibu wa kawaida wa kuhifadhi nakala kwa kutumia restic pamoja na faili zako za compose.

Kuhama kutoka bind mount kwenda named volume

Uhamishaji huu ni nakala, si kubadilisha jina, na huchukua takriban dakika moja.

docker compose down
docker volume create myapp_pgdata
docker run --rm \
  -v "$PWD/data":/from \
  -v myapp_pgdata:/to \
  alpine sh -c 'cp -a /from/. /to/'

cp -a huhifadhi umiliki, modes na timestamps, hivyo mtumiaji wa container aliyeweza kusoma saraka ya zamani ataweza kusoma volume mpya. Kisha badilisha huduma ili itumie pgdata:/var/lib/postgresql/data, ongeza pgdata kwenye block ya volumes: ya ngazi ya juu, endesha docker compose up -d, na usome logi za programu kabla ya kufuta saraka ya zamani. Kufanya kinyume chake hutumia amri ileile huku /from na /to zikibadilishwa nafasi.

Kumbuka jambo moja wakati wa majaribio. docker compose down haigusi named volumes, lakini docker compose down -v hufuta kila named volume inayotangazwa na mradi, na hakuna njia ya kutendua. Bind mount hubaki salama katika hali zote mbili, kwa sababu Docker haijawahi kumiliki saraka hiyo. Ikiwa amri za lifecycle bado ni ngeni kwako, mwongozo wa misingi ya Docker Compose kwa VPS unaelezea hatua hizo.

Kuchagua, huduma kwa huduma

Uliza ni nani anayeandika faili hiyo. Configuration unayohariri kwenye text editor na kuiweka kwenye git inapaswa kuwa kwenye bind mount, iliyowekwa kwenye :ro, kwa sababu unataka ionekane na iwe na versioning. Hali ya programu (application state) ambayo huifungui kamwe kwa mkono inapaswa kuwa kwenye named volume, kwa sababu Docker huweka ruhusa (permissions) kwa usahihi na data haitegemei njia (path) ya seva pangishi.

Kesi mchanganyiko ni media. Maktaba ya picha huandikwa na programu lakini pia husimamiwa na wewe, na mara nyingi huwa kubwa kiasi cha kuhitaji diski maalum. Iweke kwenye bind mount kwenye njia (path) iliyo kwenye diski hiyo, na uweke umiliki (ownership) kwa makusudi mara moja. Huo ndio muundo ambao stack nyingi za self-hosted hufuata: named volumes kwa ajili ya database na cache, bind mounts kwa ajili ya config na saraka kubwa unayojali. Dawati la usaidizi kama Chatwoot inayofanya kazi kwenye VPS hufikia hatua hiyo hiyo, ikiwa na Postgres kwenye named volume na viambatisho vilivyopakiwa kwenye njia (path) unayoweza kuelekeza backup yako.

FAQ

Kuna tofauti gani kati ya bind mount na named volume?

Bind mount huunganisha njia (path) ya seva pangishi (host) ndani ya container, hivyo pande zote mbili huona saraka (directory) ileile na unaweza kuibadilisha kwa kutumia zana za kawaida. Named volume ni hifadhi inayoundwa na kusimamiwa na Docker, inayotajwa kwa jina na kutangazwa katika block ya volumes: ya kiwango cha juu. Mgawanyo wa kivitendo ni umiliki: tumia bind mounts kwa usanidi (config) unaousimamia wewe, na named volumes kwa data inayotumiwa na programu yenyewe.

Kwa nini napata "permission denied" kwenye bind mount lakini si kwenye named volume?

Named volume tupu hujazwa data kutoka kwenye image, hivyo hurithi umiliki uliowekwa na image hiyo na mtumiaji wa container anaweza kuandika humo. Bind mount huonyesha saraka ya host kama ilivyo, na ikiwa Docker ililazimika kuunda saraka hiyo, basi inakuwa inamilikiwa na root. Tekeleza docker compose exec <service> id ili kuona namba ya kitambulisho (numeric id) inayotumiwa na container, kisha tumia sudo chown -R <uid>:<gid> kwenye saraka ya host, au weka user: "1000:1000" kwenye huduma hiyo.

Docker huhifadhi named volumes wapi kwenye diski?

Kwa kutumia driver ya kawaida ya local, huhifadhiwa chini ya /var/lib/docker/volumes/<volume>/_data, na docker volume inspect <volume> huonyesha Mountpoint kamili. Isome ikiwa unahitaji kukagua kitu, lakini andika humo kupitia container pekee, kwa sababu kuhariri kama root kwenye host hubadilisha umiliki kwa njia ambayo container haitatarajia.

Ninawezaje kuhifadhi nakala (backup) ya named volume?

Tekeleza container ya muda mfupi ikiwa na volume hiyo na saraka ya host zote zikiwa zimeunganishwa (mounted), kisha hamisha faili kutoka moja kwenda nyingine kwa kutumia docker run --rm -v myvol:/data:ro -v "$PWD":/backup alpine tar czf /backup/myvol.tar.gz -C /data .. Kwa database, tumia zana ya database yenyewe kutoa dump badala ya kunakili faili zilizopo, kwa sababu kunakili faili wakati data inaandikwa kunaweza kusababisha nakala iliyoharibika.

Je, docker compose down hufuta volumes zangu?

docker compose down huondoa containers na networks lakini huacha named volumes zikiwa salama. docker compose down -v hufuta pia kila named volume iliyotangazwa kwenye mradi huo, moja kwa moja. Bind mounts haziondolewi kamwe na amri yoyote kati ya hizo, kwa sababu saraka hiyo ni mali ya host na si ya Docker.