Volume va tarmoq (network)
Konteynerlar vaqtinchalik (ephemeral) โ ularni o'chirsangiz, ichidagi ma'lumot ham yo'qoladi. Ma'lumotlar bazasi uchun bu falokat! Bu darsda ma'lumotni doimiy saqlash uchun volume'larni va konteynerlarni bir-biriga bog'lash uchun tarmoq (network)'ni o'rganamiz.
Muammo: konteyner ma'lumoti yo'qoladi
Konteyner ichida yozilgan har qanday ma'lumot konteynerning o'ziga tegishli. Konteynerni docker rm bilan o'chirsangiz โ u ma'lumot bilan birga butunlay yo'qoladi.
Buni tasavvur qiling: PostgreSQL konteynerida foydalanuvchilar bazasi bor. Konteynerni yangilash yoki qayta yaratish uchun o'chirdingiz โ va barcha foydalanuvchilar ma'lumoti ketdi. Bu qabul qilib bo'lmas holat.
Yechim: volume (hajm)
Volume โ bu Docker boshqaradigan, konteynerdan tashqarida saqlanadigan ma'lumot ombori. Konteynerni o'chirsangiz ham, volume va undagi ma'lumot saqlanib qoladi. Yangi konteyner o'sha volume'ga ulanib, avvalgi ma'lumotni davom ettira oladi.
Volume'ni konteynerga ulash uchun -v bayrog'i ishlatiladi:
docker run -d \
--name baza \
-e POSTGRES_PASSWORD=parol \
-v baza-malumoti:/var/lib/postgresql/data \
postgres:16
Bu yerda -v baza-malumoti:/var/lib/postgresql/data degani: baza-malumoti nomli volume'ni konteynerning /var/lib/postgresql/data papkasiga ula. PostgreSQL o'z ma'lumotini shu papkaga yozadi โ endi u volume'da, xavfsiz saqlanadi. Konteynerni o'chirib, qayta yaratsangiz ham ma'lumot joyida qoladi.
Volume va bind mount farqi
Ma'lumot saqlashning ikki asosiy usuli bor:
- Nomli volume (named volume): Docker boshqaradi, maxsus joyda saqlanadi. Masalan
-v baza-malumoti:/data. Ma'lumotlar bazasi uchun ideal; - Bind mount: kompyuteringizdagi aniq papkani konteynerga ulaydi. Masalan
-v /home/user/loyiha:/app. Dasturlash paytida kodni jonli tahrirlash uchun qulay.
Farqni sintaksisdan bilish mumkin: agar chap tomonda oddiy nom bo'lsa โ bu volume; agar yo'l (/ bilan boshlanadi) bo'lsa โ bu bind mount:
# Nomli volume (Docker boshqaradi)
docker run -v mening-volumeim:/app/data ...
# Bind mount (kompyuterdagi aniq papka)
docker run -v /home/user/loyiha:/app ...
# Joriy papkani ulash ($(pwd) โ joriy papka yo'li)
docker run -v $(pwd):/app ...
docker volume buyruqlari
Volume'larni boshqarish uchun quyidagi buyruqlar bor:
# Barcha volume'lar ro'yxati
docker volume ls
# Yangi volume yaratish
docker volume create mening-volumeim
# Volume haqida batafsil ma'lumot
docker volume inspect mening-volumeim
# Volume'ni o'chirish
docker volume rm mening-volumeim
# Ishlatilmayotgan barcha volume'larni tozalash
docker volume prune
docker volume rm va docker volume prune volume'dagi ma'lumotni butunlay o'chiradi va uni tiklab bo'lmaydi. Muhim ma'lumot volume'larini o'chirishdan oldin ikki marta tekshiring.Muammo: konteynerlar bir-birini qanday topadi?
Endi tarmoqqa o'tamiz. Web-ilova konteyneri ma'lumotlar bazasi konteyneriga qanday ulanadi? Ular alohida, izolyatsiyalangan. IP manzillar esa konteyner har qayta ishga tushganda o'zgaradi โ shuning uchun IP'ga tayanish ishonchsiz.
Yechim โ konteynerlarni bitta tarmoq (network)ga ulash. Bir tarmoqdagi konteynerlar bir-birini nomi orqali topa oladi.
docker network โ tarmoq yaratish
Maxsus tarmoq yaratib, konteynerlarni unga ulaymiz:
# Yangi tarmoq yaratish
docker network create mening-tarmogim
# Barcha tarmoqlarni ko'rish
docker network ls
Endi ikkala konteynerni shu tarmoqqa ulab ishga tushiramiz. Bunda --network bayrog'i ishlatiladi:
# Ma'lumotlar bazasini tarmoqqa ulash
docker run -d \
--name baza \
--network mening-tarmogim \
-e POSTGRES_PASSWORD=parol \
postgres:16
# Web-ilovani o'sha tarmoqqa ulash
docker run -d \
--name web \
--network mening-tarmogim \
-e DB_HOST=baza \
-p 3000:3000 \
mening-ilovam
Xizmat nomi orqali ulanish
Diqqat qiling: web-ilovaga DB_HOST=baza deb berdik โ bu ma'lumotlar bazasi konteynerining nomi. Bir tarmoqdagi konteynerlar bir-birini nomi orqali topa oladi.
Ya'ni web-ilova kodi ichida ma'lumotlar bazasiga baza:5432 manzili orqali ulanadi โ IP manzil kerak emas! Docker ichki DNS xizmati konteyner nomini avtomatik uning joriy IP manziliga tarjima qiladi.
// Node.js ilovada ma'lumotlar bazasiga ulanish (misol)
const pool = new Pool({
host: 'baza', // konteyner nomi โ IP emas!
port: 5432,
user: 'admin',
password: 'parol',
database: 'dukon'
});
Xulosa
- Konteyner ma'lumoti vaqtinchalik โ konteynerni o'chirsangiz yo'qoladi;
- Volume โ konteynerdan tashqarida, doimiy saqlanadigan ma'lumot ombori (
-v nom:/yo'l); - Nomli volume โ Docker boshqaradi (baza uchun); bind mount โ kompyuterdagi aniq papka (kod tahrirlash uchun);
docker volume ls/create/rm/pruneโ volume'larni boshqaradi;docker network createbilan tarmoq yaratib, konteynerlarni--networkorqali ulaysiz;- Bir tarmoqdagi konteynerlar bir-birini nomi orqali topadi (IP kerak emas) โ Docker Compose buni avtomatik qiladi.