Docker / Volume ба persist data

Volume ба persist data

Container устгагдах үед дотор нь хийсэн бүх өөрчлөлт арилдаг. Volume нь контейнераас гадна өгөгдлийг хадгалдаг механизм.

Яагаад Volume хэрэгтэй вэ?

bash
# PostgreSQL container ажиллуулах
docker run -d --name db postgres:16 -e POSTGRES_PASSWORD=secret

# Өгөгдөл оруулах... 1 долоо хоног ажиллуулах...

# Container устгах
docker rm -f db

# Бүх өгөгдөл алдагдлаа! ❌

Volume ашиглавал container устгагдсан ч өгөгдөл хадгалагдана.

Гурван төрлийн хадгалалт

1. Named volume (санал болгодог)

Docker өөрөө удирддаг, /var/lib/docker/volumes/ дотор хадгалагдана.

bash
# Volume үүсгэх
docker volume create mydata

# Container-д холбох
docker run -d \
  --name db \
  -v mydata:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=secret \
  postgres:16

mydata — volume нэр, /var/lib/postgresql/data — container дотор хаанаас холбох.

2. Bind mount (хөгжүүлэлтэд)

Host машины тодорхой директорыг container-д холбоно.

bash
docker run -d \
  --name myapp \
  -v /home/user/project:/app \
  -p 3000:3000 \
  myapp

/home/user/project — host дахь директор, /app — container дотор холбогдох цэг.

3. tmpfs mount (санах ойд)

Disk-д бичихгүй, зөвхөн санах ойд — зогссоны дараа устна. Нууц мэдээлэлд тохиромжтой.

bash
docker run -d \
  --name myapp \
  --tmpfs /tmp \
  myapp

docker volume команд

bash
# Volume үүсгэх
docker volume create mydata

# Бүх volume жагсаах
docker volume ls

# Volume-ийн дэлгэрэнгүй мэдээлэл
docker volume inspect mydata

# Volume устгах
docker volume rm mydata

# Ашиглагдаагүй volume бүгдийг устгах
docker volume prune

docker volume inspect гаралт:

json
[
  {
    "Name": "mydata",
    "Driver": "local",
    "Mountpoint": "/var/lib/docker/volumes/mydata/_data",
    "CreatedAt": "2024-01-15T10:30:00Z"
  }
]

Named volume практик

PostgreSQL-ийн өгөгдлийг хадгалах:

bash
# Volume үүсгэх
docker volume create pg-data

# PostgreSQL ажиллуулах
docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_DB=mydb \
  -v pg-data:/var/lib/postgresql/data \
  postgres:16

Container устгаад дахин үүсгэвэл өгөгдөл хадгалагдана:

bash
docker rm -f postgres

docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD=secret \
  -v pg-data:/var/lib/postgresql/data \
  postgres:16

# Өгөгдөл хэвээр байна ✓

Bind mount — хөгжүүлэлтэд

Хөгжүүлэлтийн үед код өөрчлөгдсөн бүрт image дахин build хийх шаардлагагүй болохын тулд bind mount ашиглана.

bash
# Mac/Linux
docker run -d \
  --name dev-app \
  -p 3000:3000 \
  -v $(pwd):/app \
  -v /app/node_modules \
  node:20-alpine \
  sh -c "cd /app && npm install && node index.js"
  • -v $(pwd):/app — одоогийн директорыг /app-д холбох
  • -v /app/node_modulesnode_modules-ийг bind mount-ээс хасах (anonymous volume)

Windows PowerShell:

powershell
docker run -d `
  --name dev-app `
  -p 3000:3000 `
  -v ${PWD}:/app `
  node:20-alpine `
  sh -c "cd /app && npm install && node index.js"

Код өөрчлөгдсөн бүрт автоматаар тусгагдана (nodemon шиг хэрэгсэл ашиглавал server дахин эхэлнэ).

Read-only bind mount

Container дотрооc файл өөрчлөх боломжгүй болгохд:

bash
docker run -d \
  -v $(pwd)/config:/app/config:ro \
  myapp

:ro — read-only. Config файлыг container өөрчлөх боломжгүй.

Volume vs Bind mount харьцуулалт

| Шинж чанар | Named volume | Bind mount | | -------------- | ------------------------- | ----------------- | | Хадгалах газар | Docker удирддаг | Хэрэглэгч заадаг | | Хэрэглэх үе | Production өгөгдөл | Хөгжүүлэлт | | Гүйцэтгэл | Илүү хурдан (Linux) | Ойролцоо | | Backup | docker volume командаар | Файл системдээ | | Хуваалцах | Container хооронд | Host ба container |

Volume-ийн өгөгдлийг backup хийх

bash
# Volume-ийн өгөгдлийг tar архивт хадгалах
docker run --rm \
  -v mydata:/data \
  -v $(pwd):/backup \
  alpine \
  tar czf /backup/mydata-backup.tar.gz /data

# Backup-аас сэргээх
docker run --rm \
  -v mydata:/data \
  -v $(pwd):/backup \
  alpine \
  tar xzf /backup/mydata-backup.tar.gz -C /

Хэд хэдэн container нэг volume хуваалцах

bash
docker volume create shared-data

docker run -d --name app1 -v shared-data:/data myapp1
docker run -d --name app2 -v shared-data:/data myapp2

Хоёр container /data директорт нэгэн зэрэг хандана. Нэг нь бичсэн өгөгдлийг нөгөө нь уншиж болно.

Дараагийн хичээлд:

Environment variable-ийг container-д хэрхэн дамжуулах, .env файл ашиглах талаар судална.