SSD Nodes Learn 8GB RAM — ஆண்டுக்கு $66
கல்வி வழிகாட்டிகள் Matt Connorஆல் Matt Connor · புதுப்பிக்கப்பட்டது 2026-08-01

Docker Compose volumes: bind mount அல்லது named volume?

config, data எதற்கு bind mount அல்லது named volume? file permission சிக்கல்கள், inspect செய்வது, backup எடுப்பது, migrate செய்வது ஆகியவற்றை Compose எடுத்துக்காட்டுகளுடன் அறிக.

Bind mount அல்லது named volume: சுருக்கமான பதில்

Docker Compose volumes இரண்டு வகைகளாகும். எந்த தரப்பு files-க்கு உரிமையாளர் என்பதையே தேர்வு தீர்மானிக்கிறது. நீங்கள் தானாக எழுதிப் படிக்கும் files-க்கு bind mount பயன்படுத்தவும். உதாரணமாக, config, templates மற்றும் static sites. Application உரிமையாக்கிக் கையாளும் data-க்கு named volume பயன்படுத்தவும். உதாரணமாக, database files, search indexes மற்றும் uploaded media. Bind mount என்பது host-இல் உள்ள ஒரு path-ஐக் குறிக்கும். அந்த path-ஐ editor மூலம் திறக்கலாம். Named volume என்பது Docker உருவாக்கி கண்காணிக்கும் storage ஆகும். அதை Docker வழியாக அணுகலாம்.

இரண்டும் ஒரு service-க்குள் ஒரே volumes: key-ன் கீழ் தோன்றும். அதனால் அவை குழப்பப்படுகின்றன. வேறுபாடு colon-ன் இடப்பக்கத்தில் உள்ளது. . அல்லது /-ல் தொடங்கும் இடப்பக்கம் host path-ஐக் குறிக்கும். எனவே அது bind mount ஆகும். வேறு எதுவாக இருந்தாலும் அது ஒரு name ஆகும். எனவே அது named volume ஆகும். அந்த name-ஐ மேல் நிலை volumes: block-ல் அறிவிக்க வேண்டும்.

compose file-இல் உள்ள இரண்டு syntax-கள்

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 ஒரு named volume. ./nginx.conf:/etc/nginx/nginx.conf ஒரு bind mount. :ro அதை read only ஆக mount செய்கிறது. Container ஒருபோதும் மீண்டும் எழுதக்கூடாத config-க்கு இதுவே சரியான default. Top-level volumes: entry-ஐ மறந்தால், Compose service "db" refers to undefined volume pgdata உடன் நிறுத்தப்படும்.

இதைத் தொடங்கி, Docker உருவாக்கியவற்றைப் பட்டியலிடவும்:

docker compose up -d
docker volume ls

Volume-ன் பெயர் pgdata அல்ல. அதன் பெயர் <project>_pgdata. Compose file-ஐ கொண்டிருக்கும் directory-யின் பெயரே project name-க்கு default ஆகும். myapp என்ற directory, myapp_pgdata-ஐ உருவாக்கும். இது முக்கியம். ஏனெனில் directory-யின் பெயரை மாற்றினால், புதிய காலியான volume கிடைக்கும். Application தனது data-வை இழந்தது போலத் தோன்றும். உண்மையில் அது இழக்கப்படவில்லை: பழைய volume-ஐ docker volume ls இன்னும் பட்டியலிடும். Compose file-இல் name: மூலம் பெயரை நிலைப்படுத்தவும். Directory இடம் மாறக்கூடும் என்றால் COMPOSE_PROJECT_NAME-ஐ அமைக்கவும். இத்தகைய settings-ஐ உங்கள் பிற Compose environment files மற்றும் secrets உடன் வைத்திருக்கவும்.

bind mounts-க்கு மட்டும் permission errors ஏன் ஏற்படுகின்றன

இது நடைமுறையில் மிகப் பெரிய வேறுபாடு. இதற்குக் காரணம் ஒரு விதி: முதன்முதலில் பயன்படுத்தும்போது காலியாக இருக்கும் named volume, image-இலிருந்து உள்ளடக்கத்தைப் பெறுகிறது. ஆனால் bind mount அவ்வாறு பெறாது.

ஏற்கனவே image-இல் உள்ளடக்கம் கொண்ட directory மீது Docker காலியான named volume-ஐ mount செய்தால், அந்த உள்ளடக்கத்தை volume-க்கு நகலெடுக்கிறது. Image அமைத்த ownership மற்றும் modes அப்படியே பாதுகாக்கப்படுகின்றன. Official Postgres image-இல் /var/lib/postgresql/data அதன் சொந்த postgres user-க்கு சொந்தமானதாக இருக்கும். எனவே volume-க்கும் அதே numeric id ownership கிடைக்கிறது, மேலும் database தொடங்குகிறது.

bind mount இதற்கு மாறாகச் செயல்படுகிறது. Host-இல் இருப்பதே container-க்குத் தெரியும்; ownership-மும் அதில் அடங்கும். அந்த path-இல் image-இல் இருந்த உள்ளடக்கம் மறைக்கப்படுகிறது. Host directory இல்லையெனில், Docker daemon அதை உருவாக்குகிறது. Daemon root ஆக இயங்குவதால், root:root-க்கு சொந்தமான directory கிடைக்கிறது. பின்னர் non-root user ஆக இயங்கும் container process அதில் எழுத முடியாது:

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

எண்கள் ஒரே மாதிரியாக இருப்பதை உறுதி செய்வதே தீர்வு. bind mount-இல் ownership, பெயரால் அல்ல numeric user id-ஆல் ஒப்பிடப்படுகிறது. காரணம், container-க்கு தனித்த /etc/passwd உள்ளது. Container-க்குள் app எனப்படும் user, host-இல் எந்த அர்த்தமும் கொண்டிருக்காது. Uid 1000 என்பது இரு பக்கங்களிலும் uid 1000 ஆகும்.

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

docker compose exec web id, container process உண்மையில் எந்த uid-ஆக இயங்குகிறது என்பதை காட்டுகிறது. Host directory-யை அந்த எண்ணுடன் பொருந்துமாறு மாற்றுங்கள். அல்லது service-இல் user: "1000:1000" பயன்படுத்தி container-ஐ உங்கள் uid-யில் இயக்குங்கள். நீங்கள் எழுதிய application-க்கு user:-ஐ நிர்ணயிப்பது சிறந்தது. நீங்கள் எழுதாத image-க்கு host directory-யில் chown செய்வது பாதுகாப்பானது. காரணம், சில images root ஆக entrypoint-ஐத் தொடங்கி, பின்னர் privileges-ஐக் குறைத்து, கீழுள்ள குறிப்பிட்ட ownership-ஐ எதிர்பார்க்கின்றன.

மேலும் இரண்டு சிக்கல்களை அறிந்திருக்க வேண்டும். Fedora, RHEL மற்றும் SELinux (security-enhanced Linux) enforcing நிலையில் உள்ள பிற systems-இல், relabel செய்யும் வரை bind mount மறுக்கப்படும். எனவே containers இடையே பகிரப்படும் path-க்கு :z-ஐ சேர்க்கவும். ஒரே container மட்டும் பயன்படுத்த வேண்டிய path-க்கு :Z-ஐ சேர்க்கவும். இதை - ./data:/data:Z என எழுத வேண்டும். மேலும் directory-க்கு பதிலாக ஒரே file-ஐ bind mount செய்வது சிக்கலை ஏற்படுத்தும். காரணம், editor ஒன்று file-ஐ இடத்திலேயே எழுதாமல் மாற்றினால், mount முதலில் இருந்த inode-ஐப் பின்தொடரும். Container பழைய உள்ளடக்கத்தையே தொடர்ந்து பார்க்கும்; அதை மீண்டும் தொடங்கும் வரை மாற்றம் தெரியாது. அடிக்கடி edit செய்யப்படும் file-க்கு parent directory-யை mount செய்யுங்கள்.

செயல்திறன்: வேறுபாடு உண்மையில் இருக்கும் இடம்

Linux server-ல் இரண்டு வகைகளும் ஒரே kernel பாதை வழியாகச் செயல்படுகின்றன. எனவே throughput வேறுபாடு மிகவும் குறைவு. அதனால் மட்டும் அடிப்படையாகக் கொண்டு தேர்வு செய்ய வேண்டாம். இயல்புநிலை local driver-ஐ பயன்படுத்தும் named volumes, Docker-ன் மீதமுள்ள தரவுகள் இருக்கும் அதே filesystem-ல், /var/lib/docker/volumes/-ன் கீழ் சேமிக்கப்படுகின்றன. Bind mount, நீங்கள் குறிப்பிடும் இடத்தில் இருக்கும்.

Docker Desktop for macOS மற்றும் Windows-ல் இந்த வேறுபாடு தெளிவாகத் தெரியும். அங்கு containers ஒரு virtual machine-க்குள் இயங்குகின்றன. Bind mount, host filesystem-லிருந்து அந்த virtual machine-க்குள் file sharing layer வழியாகச் செல்கிறது. பல சிறிய file operations செய்யும் workloads, உதாரணமாக Node.js dependency tree அல்லது PHP framework cache, இதனால் குறிப்பிடத்தக்க அளவு மெதுவாகும். Named volumes virtual machine-க்குள் தங்குவதால் இந்தச் செலவு ஏற்படாது. அதனால்தான் பல development compose files source directory-ஐ bind-mount செய்து, node_modules மீது named volume-ஐ declare செய்கின்றன.

Bytes சேமிக்கப்படும் இடமே மற்றொரு உண்மையான வேறுபாடு. /mnt/backup-க்கு bind mount செய்தால், தரவு அந்த disk-ல் சேமிக்கப்படும். Named volume, /var/lib/docker இருக்கும் filesystem-ல் சேமிக்கப்படும். VPS-ல் அது பொதுவாக root disk ஆகும். Named volume-க்குள் வளர்ந்து வரும் database, system logs இருக்கும் அதே disk-ஐ நிரப்பும். இது incident ஆகும் முன் சரிபார்க்கவும்:

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

docker system df -v, ஒவ்வொரு volume-ஐயும் அதன் size-உடன் பட்டியலிடும். எந்த container-மும் இனி குறிப்பிடாத volumes-ஐக் குறிக்கும்.

பெயரிடப்பட்ட volume-ஐ ஆய்வு செய்தல்

பெயரிடப்பட்ட volume என்பது வெளிப்படையற்ற அமைப்பு அல்ல. அது எங்குள்ளது என்பதை Docker-இடம் கேளுங்கள்:

docker volume inspect myapp_pgdata

Mountpoint field உண்மையான host path-ஐ வழங்குகிறது; பொதுவாக அது /var/lib/docker/volumes/myapp_pgdata/_data ஆகும். அதை sudo ls மூலம் படிக்கலாம். இது விரைவான சரிபார்ப்புக்கு பயனுள்ளதாக இருக்கும். கோப்புகளைத் திருத்தும் இடமாக இதைப் பயன்படுத்த வேண்டாம். அங்கு root ஆக எழுதினால், மேலே விவரிக்கப்பட்ட ownership சிக்கல் மீண்டும் ஏற்படும். மேலும், அந்த path என்பது local driver-இன் குறிப்பிட்ட விவரம் மட்டுமே; பிற volume drivers-க்கு இது பொதுவானது அல்ல.

உள்ளடக்கத்தைப் பாதுகாப்பாகப் பார்ப்பதற்கான வழி, volume-ஐ mount செய்யும் தற்காலிக container-ஐப் பயன்படுத்துவதாகும்:

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

இது எந்த driver-க்கும் செயல்படும். உண்மையான container காணும் அதே permissions-ஐ இது காணும். --rm காரணமாக எதுவும் மீதமிருக்காது.

ஒவ்வொரு வகையையும் காப்புப்பிரதி எடுப்பது

bind mount என்பது ஒரு சாதாரண directory ஆகும். எனவே, file-level backup tool எதுவும் அதை ஏற்கனவே கையாளும். backup-ஐ host path-க்கு சுட்டினால் போதும். named volume-க்கு ஒரு கூடுதல் படி தேவை. காரணம், tool அதற்குள் செல்ல வேண்டும். volume மற்றும் ஒரு host directory ஆகிய இரண்டையும் ஒரே குறுகிய கால container-க்குள் mount செய்து, பின்னர் archive எழுதுங்கள்:

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

புதிய volume-க்கு இதை எதிர்மாறாகச் செய்து restore செய்யுங்கள்:

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

container-க்குள் root ஆக இயங்கும்போது tar numeric ownership-ஐ பாதுகாக்கிறது. இதனால் restore செய்யப்பட்ட volume-ஐ application பயன்படுத்த முடியும்.

இரண்டு வகைகளுக்கும் ஒரு எச்சரிக்கை பொருந்தும். database இயங்கிக்கொண்டிருக்கும்போது அதன் files-ஐ நகலெடுத்தால், மாறிக்கொண்டிருக்கும் தரவின் archive உருவாகும். அதை restore செய்யும்போது corrupt state ஏற்படலாம். முதலில் service-ஐ நிறுத்துங்கள். அல்லது database-ன் சொந்த tool மூலம் dump எடுக்குங்கள், docker compose exec -T db pg_dump -U postgres appdb > appdb.sql இல் காட்டியுள்ளபடி. இதனால் ஒரு plain file உருவாகும். அந்த file-ஐ உங்கள் compose files-உடன் சேர்த்து, வழக்கமான encrypted restic backup routine-க்குள் சேர்க்கலாம்.

bind mount-ஐ named volume-ஆக மாற்றுதல்

இந்த நகர்வு rename அல்ல, copy ஆகும். இதற்கு சுமார் ஒரு நிமிடம் ஆகும்.

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 ownership, modes மற்றும் timestamps-ஐ பாதுகாக்கிறது. எனவே பழைய directory-ஐ படிக்க முடிந்த container user-ஆல் புதிய volume-ஐயும் படிக்க முடியும். அதன் பிறகு service-ஐ pgdata:/var/lib/postgresql/data பயன்படுத்துமாறு மாற்றி, உயர்நிலை volumes: block-ன் தொடக்கத்தில் pgdata-ஐச் சேர்க்கவும். பின்னர் docker compose up -d-ஐ இயக்கி, பழைய directory-ஐ நீக்கும் முன் application-ன் logs-ஐப் படிக்கவும். எதிர்திசையில் மாற்ற, /from மற்றும் /to-ஐ இடமாற்றி அதே command-ஐப் பயன்படுத்தவும்.

சோதிக்கும்போது ஒரு விஷயத்தை நினைவில் கொள்ளவும். docker compose down named volumes-ஐ அப்படியே வைக்கிறது. ஆனால் docker compose down -v project குறிப்பிடும் அனைத்து named volumes-ஐயும் நீக்குகிறது. இதை மீட்டெடுக்க முடியாது. bind mount இரண்டிலும் நீடிக்கும், ஏனெனில் அந்த directory-ஐ Docker ஒருபோதும் நிர்வகிக்கவில்லை. lifecycle commands உங்களுக்கு இன்னும் புதியதாக இருந்தால், VPS-க்கான Docker Compose அடிப்படைகள் வழிகாட்டி அவற்றை விளக்குகிறது.

சேவைக்கு சேவை தேர்வு செய்தல்

கோப்பை யார் எழுதுகிறார்கள் என்பதை முதலில் தீர்மானிக்கவும். Text editor-ல் நீங்கள் திருத்தி, git-க்கு commit செய்யும் configuration, bind mount-க்கு உரியது. அதை :ro ஆக mount செய்யவும். அப்போது அது உங்களுக்குத் தெளிவாகக் காணப்படும்; version control-லும் இருக்கும். நீங்கள் கையால் ஒருபோதும் திறக்காத application state, named volume-க்கு உரியது. Docker permissions-ஐ சரியாகத் தொடக்கத்தில் அமைக்கும். தரவும் host path-ஐ சார்ந்திருக்காது.

Media என்பது கலப்பு நிலை. Photo library-ஐ application எழுதும். அதே நேரத்தில் அதை நீங்கள் நிர்வகிப்பீர்கள். அது பெரும்பாலும் குறிப்பிட்ட disk-ஐத் தேர்வு செய்யும் அளவுக்கு பெரியதாக இருக்கும். அந்த disk-ல் உள்ள path-க்கு bind mount செய்யவும். Ownership-ஐ ஒருமுறை திட்டமிட்டு அமைக்கவும். பெரும்பாலான self-hosted stacks பின்பற்றும் முறை இதுதான்: databases மற்றும் caches-க்கு named volumes, configuration-க்கும் நீங்கள் முக்கியமாகக் கருதும் பெரிய directory-க்கும் bind mounts.

FAQ

bind mount மற்றும் named volume ஆகியவற்றுக்கு இடையிலான வேறுபாடு என்ன?

bind mount, host-இல் உள்ள ஒரு path-ஐ container-க்குள் map செய்கிறது. எனவே இரு பக்கங்களும் ஒரே directory-ஐக் காணும். அதை வழக்கமான tools மூலம் edit செய்யலாம். named volume என்பது Docker உருவாக்கி நிர்வகிக்கும் storage ஆகும். இது பெயரால் குறிப்பிடப்பட்டு, top-level volumes: block-இல் அறிவிக்கப்படுகிறது. நடைமுறை வேறுபாடு ownership ஆகும்: நீங்கள் பராமரிக்கும் config-க்கு bind mounts பயன்படுத்தவும்; application பராமரிக்கும் data-க்கு named volumes பயன்படுத்தவும்.

named volume-இல் இல்லாமல் bind mount-இல் "permission denied" ஏன் கிடைக்கிறது?

காலியான named volume, image-இலிருந்து ஆரம்ப data-ஐப் பெறுகிறது. எனவே image அமைத்த ownership அதற்குப் பெறப்படுகிறது. Container user அதில் எழுத முடியும். bind mount, host directory-யின் நிலையை அப்படியே காட்டுகிறது. Docker அந்த directory-ஐ உருவாக்க வேண்டியிருந்தால், அது root-க்கு சொந்தமானதாக உருவாக்கப்படும். Container பயன்படுத்தும் numeric id-ஐப் பார்க்க docker compose exec <service> id இயக்கவும். பின்னர் host directory-க்கு sudo chown -R <uid>:<gid> இயக்கவும். அல்லது service-இல் user: "1000:1000" அமைக்கவும்.

Docker named volumes-ஐ disk-இல் எங்கே சேமிக்கிறது?

இயல்புநிலை local driver-ஐப் பயன்படுத்தும்போது, அவை /var/lib/docker/volumes/<volume>/_data-இன் கீழ் சேமிக்கப்படுகின்றன. சரியான Mountpoint-ஐ docker volume inspect <volume> அச்சிடுகிறது. ஏதேனும் சரிபார்க்க வேண்டுமெனில் அதை வாசிக்கலாம். ஆனால் அதில் எழுதுவது container மூலம் மட்டுமே இருக்க வேண்டும். ஏனெனில் host-இல் root ஆக edit செய்வது ownership-ஐ மாற்றும். இதனால் container எதிர்பார்க்காத நிலை ஏற்படும்.

named volume-ஐ எவ்வாறு backup செய்வது?

volume மற்றும் host directory இரண்டையும் mount செய்து, குறுகிய காலம் மட்டும் இயங்கும் container-ஐ தொடங்கவும். பின்னர் docker run --rm -v myvol:/data:ro -v "$PWD":/backup alpine tar czf /backup/myvol.tar.gz -C /data . மூலம் ஒன்றிலிருந்து மற்றொன்றுக்கு archive உருவாக்கவும். Database-க்கு, live files-ஐ நகலெடுப்பதற்குப் பதிலாக database-ன் சொந்த tool மூலம் dump எடுக்கவும். எழுதும் செயல்பாடுகள் நடந்து கொண்டிருக்கும்போது எடுக்கப்படும் file copy, restore செய்யும்போது corrupt state-ஐ உருவாக்கக்கூடும்.

docker compose down எனது volumes-ஐ நீக்குமா?

docker compose down containers மற்றும் networks-ஐ நீக்குகிறது. named volumes-ஐ அப்படியே வைத்திருக்கிறது. docker compose down -v project அறிவிக்கும் ஒவ்வொரு named volume-ஐயும் நிரந்தரமாக நீக்குகிறது. Bind mounts-ஐ எந்த command-மும் நீக்காது. காரணம், அந்த directory host-க்கு சொந்தமானது; Docker-க்கு அல்ல.