Mundarija (35)
- Bu darsda
- 1. Nega bu kerak?
- 2. Uch usul
- 3. Named volume: bazani saqlab qolish
- 3.1 Volume yaratish va ko'rish
- 3.2 Tajriba: konteyner o'chadi, ma'lumot qoladi
- 3.3 Volume ichida nima bor
- 4. PostgreSQL 18: volume yo'li o'zgardi
- 4.1 Eski yo'l bilan nima bo'ladi
- 4.2 Nega shunday o'zgartirildi
- 5. Volume zaxirasi
- 5.1 tar bilan nusxa
- 5.2 Halol eslatma: bu zaxira ishonchlimi?
- 6. Bind mount: kompyuterdagi papka
- 6.1 Faylni konteynerga berish
- 6.2 Ruxsatlar muammosi
- 6.3 Bind mount xavfi
- 7. tmpfs: faqat xotirada
- 8. Volume'larni boshqarish va docker volume rm xavfi
- 8.1 Ro'yxat va o'chirish
- 8.2 Nega bu buyruq xavfli
- 9. SQL qadami: bu darsdan nima olamiz
- 10. Ko'p uchraydigan xatolar
- 10.1 Eski volume yo'li
- 10.2 -v ni unutish
- 10.3 Ishlab turgan bazadan nusxa
- 10.4 Windows yo'llari Git Bash'da
- 11. Mashqlar
- 1-mashq (oson): qaysi usul?
- 2-mashq (o'rta): ma'lumot saqlanganini isbotlang
- 3-mashq (qiyin): to'g'ri docker run buyrug'ini yig'ish
- 4-mashq: SQL qadami — ishonchli zaxira
- 12. Real ishda
- Xulosa
- Manbalar
Docker volume va bind mount: konteynerda ma'lumotni saqlash
Qisqacha: Konteyner o'chirilsa, uning ichiga yozilgan fayllar ham o'chadi. Shuning uchun ma'lumot konteynerdan tashqariga yoziladi: named volume (Docker boshqaradigan nomli saqlash joyi — baza uchun eng yaxshi tanlov), bind mount (kompyuteringizdagi papka konteynerga ulanadi) yoki tmpfs (faqat xotirada, vaqtinchalik). PostgreSQL 18 image'ida volume
/var/lib/postgresqlga ulanadi — eski qo'llanmalardagi/var/lib/postgresql/dataendi xato beradi.
Bu darsda
- Konteyner o'chirilganda ma'lumot qayerga ketishini va uni qanday saqlab qolishni tushuntira olasiz.
- Named volume yaratib, Postgres bazasini konteynerni almashtirgandan keyin ham saqlab qolasiz.
- PostgreSQL 18 image'idagi yangi volume yo'lini va eski yo'l nima uchun xato berishini bilasiz.
- Bind mount bilan kompyuterdagi faylni konteynerga berasiz va Windows'dagi ruxsatlar muammosini tushunasiz.
- Volume zaxirasini olasiz, tmpfs'ni ishlatasiz va
docker volume rmxavfini bilasiz.
Oldin bilishingiz kerak: Image, container va registry: asosiy buyruqlar, Fayl ruxsatlari va foydalanuvchilar, Fayl tizimi: papkalar daraxti va fayllar.
1. Nega bu kerak?
Oldingi darsda Postgres konteynerini ishga tushirdingiz, keyin docker rm -f bilan o'chirdingiz. Shunda baza qayerga ketdi? Javob ikki xil bo'lishi mumkin:
- Konteynerning o'z yoziladigan qatlamiga yozilgan bo'lsa — konteyner bilan birga yo'qoladi.
postgresimage'ida esa baza papkasiVOLUMEdeb e'lon qilingan. Shuning uchun Docker anonim volume yaratgan edi. Konteyner o'chdi, anonim volume qoldi — lekin nomsiz, unga hech kim qaytib ulanmaydi.
Ikkala holat ham yaramaydi. Bizga shunday baza kerak: konteynerni o'chirib, PostgreSQL'ning yangi tuzatish versiyasi bilan qayta yaratsak ham, hamma jadval joyida qolsin.
Hayotiy o'xshatish: mehmonxona va uydagi seyf. Konteyner — mehmonxona xonasi: ketganingizdan keyin uni tozalab, boshqa mehmonga beradi. Xonada qoldirilgan narsa yo'qoladi. Volume — o'z seyfingiz: istalgan xonaga olib kirasiz, ketganda o'zingiz bilan olib chiqasiz. Xona almashadi, seyf ichidagi narsa — yo'q.
2. Uch usul
Docker konteynerga tashqi saqlash joyini uch usulda ulaydi. Sxemaga qarang — har usulda ma'lumot jismoniy jihatdan qayerda turadi:
flowchart LR
V["Named volume: Docker hududi"] -->|"-v nom:/yol"| C["Konteyner"]
B["Bind mount: sizning papkangiz"] -->|"-v papka:/yol"| C
T["tmpfs: faqat RAM"] -->|"--tmpfs /yol"| C| Usul | Ma'lumot qayerda | Kim boshqaradi | Qachon |
|---|---|---|---|
| Named volume | Docker hududi (/var/lib/docker/volumes) |
Docker | baza, doimiy ma'lumot |
| Bind mount | host'dagi istalgan papka | siz | kod, sozlama, SQL fayllar |
| tmpfs | operativ xotira | kernel | vaqtinchalik, maxfiy fayl |
Uchala usulda ham konteyner ichida oddiy papka ko'rinadi. Konteyner ichidagi dastur farqni sezmaydi — Postgres o'z fayllarini qayerga yozayotganini bilmaydi. Farq faqat tashqarida.
3. Named volume: bazani saqlab qolish
3.1 Volume yaratish va ko'rish
Volume — Docker yaratadigan va boshqaradigan saqlash joyi. Uning nomi bor, konteynerdan alohida yashaydi.
docker volume create kanon26-dars
docker volume inspect kanon26-darsNatija:
kanon26-dars
[
{
"CreatedAt": "2026-10-24T03:02:18Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/kanon26-dars/_data",
"Name": "kanon26-dars",
"Options": null,
"Scope": "local"
}
]Mountpoint — volume fayllari jismoniy turgan joy. Windows'da bu yo'l Windows Explorer'da yo'q: u Docker Desktop'ning WSL2 VM'i ichida. Driver: local — oddiy lokal disk. Boshqa driver'lar tarmoq diskiga yoki bulutga ham yoza oladi.
docker volume create ni yozish shart emas: docker run -v nom:/yol volume yo'q bo'lsa, uni o'zi yaratadi. Lekin aniq yaratish tushunarliroq.
3.2 Tajriba: konteyner o'chadi, ma'lumot qoladi
Volume'ni Postgres konteyneriga ulaymiz:
docker run -d --name kanon26-v1 \
-e POSTGRES_HOST_AUTH_METHOD=trust \
-v kanon26-dars:/var/lib/postgresql \
postgres:18-v kanon26-dars:/var/lib/postgresql — "kanon26-dars volume'ini konteyner ichidagi /var/lib/postgresql papkasiga ula". POSTGRES_HOST_AUTH_METHOD=trust — parolsiz ulanish; faqat shu tajriba uchun, port ochilmagan.
Bazaga bitta jadval va bitta qator yozamiz:
docker exec kanon26-v1 psql -U postgres -c \
"create table eslatma(matn text);
insert into eslatma values ('Volume ichida saqlanadi');"Natija:
CREATE TABLE
INSERT 0 1SQL buyruqlarini hali bilmaysiz — SQL tili va buyruq turlari darsida o'rganasiz. Qo'shtirnoq ichidagi yangi qator SQL uchun oddiy bo'shliq, ikki buyruq ; bilan ajralgan. Hozir ma'nosi yetarli: eslatma jadvali yaratildi va unga bitta matn yozildi.
Endi konteynerni butunlay o'chiramiz va xuddi shu volume bilan yangisini yaratamiz:
docker rm -f kanon26-v1
docker run -d --name kanon26-v2 \
-e POSTGRES_HOST_AUTH_METHOD=trust \
-v kanon26-dars:/var/lib/postgresql \
postgres:18
docker exec kanon26-v2 psql -U postgres -c "table eslatma;"Natija (oxirgi buyruq):
matn
-------------------------
Volume ichida saqlanadi
(1 row)Yangi konteyner, eski ma'lumot. kanon26-v1 endi yo'q, lekin uning yozgani kanon26-v2 da turibdi. Ikkinchi konteyner ishga tushganda Postgres volume'da tayyor bazani ko'rdi va uni qaytadan yaratmadi.
Tekshirib ko'ring: Ikkinchi konteynerda
-vni unutsangiz,table eslatma;nima beradi?
Javob
Xato beradi — jadval yo'q. -v siz Docker yangi anonim volume yaratadi va Postgres u yerda bo'sh baza quradi. Eski ma'lumot kanon26-dars da xavfsiz turibdi, lekin yangi konteyner unga ulanmagan. Xato matni — ERROR: relation "eslatma" does not exist ("eslatma" jadvali mavjud emas; matnni o'z PostgreSQL 17.6 bazamizda tekshirdik). Bu xatoni SQL darslarida ko'p uchratasiz.
3.3 Volume ichida nima bor
Volume ulangan papkaga qaraymiz:
docker exec kanon26-v2 \
ls /var/lib/postgresql /var/lib/postgresql/18/dockerRo'yxat uzun. Hozir faqat ikki narsani toping: ildizdagi 18 papkasi va ichkaridagi pg_wal hamda postgresql.conf.
/var/lib/postgresql:
18
/var/lib/postgresql/18/docker:
base
global
pg_commit_ts
pg_dynshmem
pg_hba.conf
pg_ident.conf
pg_logical
pg_multixact
pg_notify
pg_replslot
pg_serial
pg_snapshots
pg_stat
pg_stat_tmp
pg_subtrans
pg_tblspc
pg_twophase
PG_VERSION
pg_wal
pg_xact
postgresql.auto.conf
postgresql.conf
postmaster.opts
postmaster.pidVolume ildizida bitta 18 papkasi — asosiy versiya raqami. Uning ichidagi docker papkasi — Postgres'ning ma'lumotlar katalogi (data directory): jadvallar (base), o'zgarishlar jurnali (pg_wal), sozlamalar (postgresql.conf, pg_hba.conf). Bu fayllarni qo'lda tahrirlamang. Ularning ma'nosini qismning keyingi darslarida birma-bir ochamiz.
4. PostgreSQL 18: volume yo'li o'zgardi
4.1 Eski yo'l bilan nima bo'ladi
Internetdagi qo'llanmalarning ko'pchiligi (va AI yordamchilarining javoblari) shunday yozadi: -v nom:/var/lib/postgresql/data. Bu 17 va undan oldingi image'lar uchun to'g'ri edi. 18 da sinab ko'ramiz:
docker run --name kanon26-eski \
-e POSTGRES_HOST_AUTH_METHOD=trust \
-v kanon26-eski:/var/lib/postgresql/data \
postgres:18Natija uzun. Unda ikki alohida xabar bor: yulduzchalar orasidagi WARNING va undan keyingi Error. Ikkinchisi muhimroq.
********************************************************************************
WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow
anyone with access to the Postgres port to access your database without
a password, even if POSTGRES_PASSWORD is set. See PostgreSQL
documentation about "trust":
https://www.postgresql.org/docs/current/auth-trust.html
In Docker's default configuration, this is effectively any other
container on the same system.
It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace
it with "-e POSTGRES_PASSWORD=password" instead to set a password in
"docker run".
********************************************************************************
Error: in 18+, these Docker images are configured to store database data in a
format which is compatible with "pg_ctlcluster" (specifically, using
major-version-specific directory names). This better reflects how
PostgreSQL itself works, and how upgrades are to be performed.
See also https://github.com/docker-library/postgres/pull/1259
Counter to that, there appears to be PostgreSQL data in:
/var/lib/postgresql/data (unused mount/volume)
This is usually the result of upgrading the Docker image without
upgrading the underlying database using "pg_upgrade" (which requires both
versions).
The suggested container configuration for 18+ is to place a single mount
at /var/lib/postgresql which will then place PostgreSQL data in a
subdirectory, allowing usage of "pg_upgrade --link" without mount point
boundary issues.
See https://github.com/docker-library/postgres/issues/37 for a (long)
discussion around this process, and suggestions for how to do so.Ikki xabar chiqdi. Avval tarjima qilamiz.
Ogohlantirish (WARNING): "trust yoqilgan. Postgres portiga yeta oladigan har kim parolsiz kiradi — hatto parol berilgan bo'lsa ham. Docker'ning sukut sozlamasida bu — shu kompyuterdagi boshqa har qanday konteyner." Biz buni bilib qildik: tajriba, port ochilmagan.
Xato (Error): "18 va undan keyingi image'lar bazani versiya raqamli papkalarda saqlaydi. /var/lib/postgresql/data da esa ma'lumot bor ko'rinadi (ishlatilmagan volume). Odatda bu image yangilanib, baza pg_upgrade bilan yangilanmaganda bo'ladi. 18+ uchun tavsiya: bitta volume'ni /var/lib/postgresql ga ulang."
Konteyner exit kod 1 bilan to'xtadi — baza umuman ishga tushmadi. Image sizni "bazamni yo'qotdim" holatidan himoya qildi.
4.2 Nega shunday o'zgartirildi
Oldingi darsda docker image inspect da ikki maydon ko'rgan edik: VOLUME /var/lib/postgresql va PGDATA=/var/lib/postgresql/18/docker. Endi ma'nosi aniq:
- Volume — bitta,
/var/lib/postgresqlda. - Baza — uning ichida
18/dockerpapkasida.
Keyinchalik 19-versiyaga o'tganda, xuddi shu volume ichida 19/docker paydo bo'ladi. Postgres'ning asosiy versiyalari orasida baza fayllari formati o'zgaradi, eski fayllarni yangi versiya to'g'ridan o'qiy olmaydi. Ko'chirish vositasi pg_upgrade ikkala papkani bitta disk ichida ko'rsa, tez ishlaydi. Image mualliflari shuning uchun yo'lni o'zgartirdi.
Diqqat: Eski qo'llanma yoki eski
docker-compose.ymldan nusxa ko'chirsangiz,/var/lib/postgresql/datani/var/lib/postgresqlga almashtiring. Bu kursda doim to'g'ri yo'lni ishlatamiz.
5. Volume zaxirasi
5.1 tar bilan nusxa
Volume — Docker hududida. Uni oddiy fayl sifatida nusxalash uchun kichik hiyla ishlatiladi: vaqtinchalik konteyner yaratamiz, unga ikki narsani ulaymiz — zaxiralanadigan volume va kompyuterdagi papka. Ichida esa tar bilan arxiv qilamiz. tar — fayllarni bitta arxivga yig'adigan Linux dasturi, czf — yaratish, gzip bilan siqish, fayl nomi.
P=$(cygpath -w "$PWD/bind")
docker run --rm \
-v kanon26-dars:/manba:ro \
-v "$P:/zaxira" \
postgres:18 tar czf /zaxira/kanon26-dars.tgz -C /manba .Har qatorni o'qiymiz:
cygpath -w— Git Bash yo'lini Windows yo'liga (C:\...) aylantiradi.P— joriy papkadagibindpapkasining Windows yo'li.-v kanon26-dars:/manba:ro— volume konteyner ichida/manbabo'ladi.:ro— read-only, faqat o'qish: zaxira olayotganda volume'ni tasodifan buzib qo'ymaymiz.-v "$P:/zaxira"— kompyuterdagi papka konteyner ichida/zaxirabo'ladi. Bu — bind mount, uni keyingi bo'limda ochamiz.postgres:18 tar ...— alohida image yuklamaslik uchunpostgres:18ning o'zidagitardan foydalandik.
Buyruq hech narsa chiqarmadi va exit kod 0 bilan tugadi. Arxiv bind papkasida paydo bo'ldi: 4 825 644 bayt, ya'ni ~4.8 MB (keyingi bo'limdagi ro'yxatda ko'rinadi). Bo'sh Postgres bazasi siqilgan holda shuncha joy oladi.
5.2 Halol eslatma: bu zaxira ishonchlimi?
Biz bu arxivni kanon26-v2 ishlab turganda oldik. Postgres shu paytda fayllarga yozayotgan bo'lishi mumkin edi. Ishlab turgan bazaning fayllarini nusxalash — yarim yozilgan sahifani ham nusxalash xavfi. Bunday arxivdan tiklangan baza ishga tushmasligi mumkin.
To'g'ri usullar:
- Arxivdan oldin konteynerni to'xtating:
docker stop, keyintar, keyindocker start. - Yoki Postgres'ning o'z zaxira vositasi
pg_dumpbilan — u ishlab turgan bazadan ham izchil nusxa oladi. Uni Backup va restore darsida o'rganasiz.
Arxivdan tiklash teskari buyruq bilan bo'ladi: bo'sh yangi volume, vaqtinchalik konteyner va tar xzf (ochish). Tiklashni biz sinab ko'rmadik — shuning uchun bu yerda tayyor buyruq bermaymiz. Qoida: tiklab ko'rilmagan zaxira — zaxira emas.
6. Bind mount: kompyuterdagi papka
6.1 Faylni konteynerga berish
Bind mount — host'dagi mavjud papkani yoki faylni konteyner ichiga ulash. Volume'dan farqi: joyni siz tanlaysiz va fayllarni Windows'da oddiy dastur bilan ochasiz.
Bu kursda bind mount'ning eng foydali ishi — SQL fayllarni konteynerga berish. Bitta SQL faylni yaratamiz va konteyner ichidan ko'ramiz:
echo "select 'bind mount orqali kelgan fayl' as xabar;" \
> bind/salom.sql
P=$(cygpath -w "$PWD/bind")
docker run --rm -e POSTGRES_HOST_AUTH_METHOD=trust \
-v "$P:/sql:ro" postgres:18 \
sh -c 'ls -la /sql; id; stat -c "%U %a %n" /sql/salom.sql'Natija:
total 4720
drwxrwxrwx 1 root root 4096 Oct 24 03:00 .
drwxr-xr-x 1 root root 4096 Oct 24 03:02 ..
-rw-r--r-- 1 root root 4825644 Oct 24 03:02 kanon26-dars.tgz
-rwxrwxrwx 1 root root 49 Oct 24 03:02 salom.sql
uid=0(root) gid=0(root) groups=0(root)
root 777 /sql/salom.sqlKonteyner ichida /sql papkasida ikkala fayl bor: Windows'da yaratilgan salom.sql va oldingi bo'limdagi zaxira arxivi. Ular nusxa emas — o'sha fayllarning o'zi. Windows'da salom.sql ni o'zgartirsangiz, konteyner yangi matnni darhol ko'radi.
id — konteyner ichidagi jarayon root (uid 0) nomidan ishlayotganini ko'rsatdi. stat -c "%U %a %n" — fayl egasi, ruxsat raqami va nomi.
6.2 Ruxsatlar muammosi
Fayl ruxsatlari darsida rwx, chmod 644 va fayl egasini o'rgangansiz. Endi natijaga diqqat bilan qarang:
- Hamma fayl egasi —
root root. Windows'da fayl egasi sizning foydalanuvchingiz edi. salom.sqlruxsati —777(-rwxrwxrwx): hamma o'qiydi, yozadi va bajaradi.
Sabab: Windows'ning NTFS fayl tizimida Linux egalari va rwx ruxsatlari yo'q. Docker Desktop Windows papkasini Linux'ga uzatganda, ruxsatlarni "o'ylab topadi": egasi doim root, ruxsatlar keng. Konteyner ichida chmod yoki chown qilsangiz ham, Windows fayliga haqiqiy ruxsat yozilmaydi.
Bu nimaga ta'sir qiladi:
- Ba'zi dasturlar o'z fayllarining ruxsatini tekshiradi. PostgreSQL ma'lumotlar katalogi uchun qat'iy ruxsat talab qiladi (faqat egasi kira olsin,
0700). Shuning uchun Postgres bazasini Windows papkasiga bind mount qilish muammoli. Biz buni sinamadik — baza uchun named volume ishlatamiz. - Linux server'da esa teskari muammo: konteyner ichidagi jarayon
rootdan boshqa foydalanuvchi (masalan uid 999) nomidan ishlasa, host papkasiga yozolmayPermission deniedberadi. Bu deploy qismlarida uchraydi. - Docker hujjati Windows papkalarini konteynerga ulashni sekinroq deb ogohlantiradi va loyihalarni WSL2 fayl tizimida saqlashni tavsiya qiladi. Tezlikni biz o'lchamadik.
Tekshirib ko'ring: Nega zaxira olishda volume'ni
:robilan,/zaxirapapkasini esa:rosiz uladik?
Javob
Volume'dan faqat o'qiymiz — :ro uni tasodifiy o'zgarishdan himoya qiladi. /zaxira ga esa arxivni yozishimiz kerak — :ro bo'lsa, tar yoza olmasdi va Read-only file system xatosini berardi. Qoida: konteynerga faqat kerakli darajadagi huquqni bering.
6.3 Bind mount xavfi
Bind mount konteynerga host'ning haqiqiy fayllarini ochadi. Konteyner ichidagi jarayon root bo'lsa, ulangan papkadagi hamma narsani o'chira oladi. Shuning uchun:
- Faqat kerakli papkani ulang — butun
C:\Usersyoki/ni emas. - O'qish yetarli bo'lsa —
:ro. - Begona image'ga uy papkangizni ulamang: u yerda SSH kalitlar, brauzer ma'lumotlari,
.envfayllar turadi.
7. tmpfs: faqat xotirada
tmpfs — operativ xotirada (RAM) yashaydigan vaqtinchalik fayl tizimi. Diskka hech narsa yozilmaydi. Konteyner to'xtashi bilan ichidagi hamma narsa yo'qoladi.
docker run --rm --tmpfs /tmp/vaqtincha:size=16m postgres:18 \
sh -c 'df -h /tmp/vaqtincha; echo salom > /tmp/vaqtincha/f;
cat /tmp/vaqtincha/f'Natija:
Filesystem Size Used Avail Use% Mounted on
tmpfs 16M 0 16M 0% /tmp/vaqtincha
salomdf -h — disk joyini ko'rsatadi. /tmp/vaqtincha — tmpfs, hajmi biz bergan 16 MB. Faylga salom yozildi va o'qildi. Konteyner tugadi — fayl ham yo'q.
Qachon kerak: juda tez vaqtinchalik fayllar, yoki diskka hech qachon tushmasligi kerak bo'lgan maxfiy ma'lumot. Postgres bazasini tmpfs'da saqlash testlarni tezlashtiradi — lekin baza har safar yo'qoladi. tmpfs faqat Linux konteynerlarida ishlaydi.
8. Volume'larni boshqarish va docker volume rm xavfi
8.1 Ro'yxat va o'chirish
docker volume ls --filter name=kanon26
docker volume rm kanon26-dars
docker volume ls --filter name=kanon26Natija:
DRIVER VOLUME NAME
local kanon26-dars
kanon26-dars
DRIVER VOLUME NAMEBirinchi ro'yxatda kanon26-dars bor. docker volume rm uni o'chirdi va nomini qaytardi. Ikkinchi ro'yxat bo'sh.
8.2 Nega bu buyruq xavfli
E'tibor bering: Docker hech narsa so'ramadi. "Ishonchingiz komilmi?" degan savol, savat (korzina), "bekor qilish" — hech biri yo'q. eslatma jadvali, Volume ichida saqlanadi qatori, butun baza — bir buyruq bilan yo'q bo'ldi va qaytarib bo'lmaydi.
Faqat bitta himoya bor: volume'ni ishlatayotgan konteyner bo'lsa (hatto to'xtagan bo'lsa ham), Docker uni o'chirishga ruxsat bermaydi. Shuning uchun biz avval kanon26-v2 ni o'chirgan edik.
Yana xavfli buyruqlar:
docker volume prune— hech qaysi konteyner ishlatmayotgan volume'larni o'chiradi. To'xtatib, o'chirib qo'ygan konteyneringizning bazasi ham shu ro'yxatga tushadi.docker rm -v— konteyner bilan birga uning anonim volume'larini o'chiradi (nomli volume'larga tegmaydi).docker system prune --volumes— hamma ishlatilmayotgan narsani, volume'lar bilan birga.
Qoida: volume o'chirishdan oldin — nomini ikki marta o'qing, kerak bo'lsa zaxira oling. Server'da esa bu buyruqlarni faqat zaxira tekshirilgandan keyin.
Diqqat: "Disk to'lib qoldi" degan muammoni internetdagi maslahat bilan
docker system prune -a --volumesorqali "hal qilish" — real kompaniyalarda baza yo'qotishning ma'lum sabablaridan biri. Avvaldocker system dfbilan nima joy egallayotganini ko'ring.
9. SQL qadami: bu darsdan nima olamiz
Bu darsda loyihaga commit yo'q — faqat tajriba. Lekin uning natijasi keyingi darslarda to'g'ridan ishlatiladi. PostgreSQL o'rnatish va ulanish darsida vazifalar bazasining doimiy konteynerini yaratamiz. U shunday ulanadi:
- named volume
kanon26-data→/var/lib/postgresql(18 uchun to'g'ri yo'l); - port faqat
127.0.0.1da; - SQL fayllar konteynerga beriladi va
psqlbilan bajariladi.
Shunda konteynerni istalgan paytda o'chirib qayta yaratish mumkin — bazangiz volume'da xavfsiz.
10. Ko'p uchraydigan xatolar
10.1 Eski volume yo'li
Error: in 18+, these Docker images are configured to store database data in a format which is compatible with "pg_ctlcluster" — yuqorida ko'rdik. Yechim: -v nom:/var/lib/postgresql.
10.2 -v ni unutish
Konteyner ishlaydi, baza bor, hammasi joyida. Bir kuni docker rm va qayta docker run — jadvallar yo'q. Ma'lumot anonim volume'da qolib ketgan. Yechim: doim nomli volume bering. Agar shunday bo'lib qolsa — docker volume ls da 64 belgili nomlarni qidiring, ma'lumot o'sha yerda bo'lishi mumkin. Shoshib prune qilmang.
10.3 Ishlab turgan bazadan nusxa
Fayllarni tar yoki oddiy nusxa bilan olish — baza ishlab turgan paytda buzilgan zaxira beradi. Yechim: to'xtatib nusxa yoki pg_dump.
10.4 Windows yo'llari Git Bash'da
Git Bash / bilan boshlanadigan argumentlarni ba'zan Windows yo'liga "o'zi aylantiradi". -v dagi yo'l kutilmagan joyga ulanadi. Yechim: host yo'lini cygpath -w bilan aniq Windows ko'rinishida bering (yuqoridagidek). Yoki bind mount buyruqlarini PowerShell'da yozing: -v "${PWD}\bind:/sql:ro".
11. Mashqlar
Mashqlar kurs/mashqlar/26/03-volume/ da.
1-mashq (oson): qaysi usul?
Har vaziyat uchun named volume, bind mount yoki tmpfs ni tanlang:
- Postgres bazasi — konteyner yangilansa ham saqlansin.
- Windows'da tahrirlayotgan
sxema.sqlfaylingizni konteynerdagipsqlga berish. - Testlar har safar toza bazada tez ishlasin, ma'lumot saqlanishi shart emas.
- Zaxira arxivini Windows papkangizga chiqarish.
Yechim
- Named volume — Docker boshqaradi, ruxsatlar to'g'ri, konteynerdan mustaqil.
- Bind mount (
:robilan) — fayl Windows'da, konteyner uni darhol ko'radi. - tmpfs — RAM'da, tez, konteyner bilan yo'qoladi.
- Bind mount — arxiv Windows'dagi papkaga tushishi kerak; zaxira volume'i esa
:robilan ulanadi.
2-mashq (o'rta): ma'lumot saqlanganini isbotlang
Buyruqlarni yozing: mashq-data volume'i bilan pg-a konteynerini yarating, eslatma jadvaliga 'Birinchi konteyner' matnini yozing, pg-a ni o'chiring, xuddi shu volume bilan pg-b ni yarating va matnni o'qing. Oxirida hammasini tozalang.
Ishora: «Tajriba: konteyner o'chadi, ma'lumot qoladi» bo'limidagi buyruqlarni nomlarini almashtirib ishlating. -e POSTGRES_HOST_AUTH_METHOD=trust port ochilmagani uchun bu yerda mumkin.
Yechim
docker run -d --name pg-a -e POSTGRES_HOST_AUTH_METHOD=trust \
-v mashq-data:/var/lib/postgresql postgres:18
docker exec pg-a psql -U postgres -c \
"create table eslatma(matn text);
insert into eslatma values ('Birinchi konteyner');"
docker rm -f pg-a
docker run -d --name pg-b -e POSTGRES_HOST_AUTH_METHOD=trust \
-v mashq-data:/var/lib/postgresql postgres:18
docker exec pg-b psql -U postgres -c "table eslatma;"
docker rm -f pg-b
docker volume rm mashq-datapg-b dagi natija — Birinchi konteyner qatori (darsdagi kanon26-v2 chiqishi kabi). Agar pg-b dagi psql "connection refused" kabi xato bersa — Postgres hali ishga tushib ulgurmagan: bir-ikki soniya kutib qayta urining yoki docker logs pg-b da ready to accept connections ni kuting. Tozalash tartibi muhim: avval konteyner, keyin volume — aks holda Docker volume'ni "ishlatilmoqda" deb o'chirmaydi.
3-mashq (qiyin): to'g'ri docker run buyrug'ini yig'ish
Jamoangizda Postgres versiyasi har xil (16, 17, 18). postgresBuyrugi({ nom, volume, port, versiya }) funksiyasini yozing. U docker run uchun argumentlar massivini qaytarsin. Talablar:
- volume yo'li: versiya 18 va undan katta —
/var/lib/postgresql, kichik —/var/lib/postgresql/data; - port faqat
127.0.0.1da; - port 1024–65535 oralig'ida bo'lmasa —
RangeErrortashlasin.
Natijani ["docker", ...args].join(" ") bilan chiqaring. Ishora: shart uchun ternar operator, xato uchun throw new RangeError(...) (throw va Error obyekti).
Yechim
function postgresBuyrugi({ nom, volume, port, versiya }) {
if (!Number.isInteger(port) || port < 1024 || port > 65535) {
throw new RangeError(`Port noto'g'ri: ${port}`);
}
const yol =
versiya >= 18 ? "/var/lib/postgresql"
: "/var/lib/postgresql/data";
return [
"run", "-d", "--name", nom,
"-v", `${volume}:${yol}`,
"-p", `127.0.0.1:${port}:5432`,
`postgres:${versiya}`,
];
}
const yangi = postgresBuyrugi({
nom: "pg18", volume: "pg18-data", port: 5499, versiya: 18,
});
console.log(["docker", ...yangi].join(" "));
const eski = postgresBuyrugi({
nom: "pg16", volume: "pg16-data", port: 5416, versiya: 16,
});
console.log(["docker", ...eski].join(" "));
try {
postgresBuyrugi({ nom: "x", volume: "x", port: 80, versiya: 18 });
} catch (e) {
console.log(`${e.name}: ${e.message}`);
}Konsolda:
docker run -d --name pg18 -v pg18-data:/var/lib/postgresql -p 127.0.0.1:5499:5432 postgres:18
docker run -d --name pg16 -v pg16-data:/var/lib/postgresql/data -p 127.0.0.1:5416:5432 postgres:16
RangeError: Port noto'g'ri: 80Satr emas, massiv qaytarish — ataylab. Massivni child_process.spawn("docker", args) ga to'g'ridan berish mumkin: har argument alohida, shell ishtirok etmaydi. child_process darsidagi shell injection xavfi shu bilan yo'qoladi. 1024 dan kichik portlar Linux'da maxsus huquq talab qiladi — shuning uchun ular rad etildi.
4-mashq: SQL qadami — ishonchli zaxira
mashq-datavolume'i bilan Postgres konteyneri yarating va bitta jadval yozing (2-mashq).- Konteynerni to'xtating (
docker stop). - «
tarbilan nusxa» bo'limidagi usul bilan volume'nizaxira.tgzga arxivlang. - Konteynerni qayta yoqing va jadval joyida ekanini tekshiring.
- Arxiv hajmini darsdagi 4.8 MB bilan solishtiring.
Yechim
2–4. docker stop pg-a → tar buyrug'i (-v mashq-data:/manba:ro) → docker start pg-a → docker exec pg-a psql -U postgres -c "table eslatma;". To'xtatilgan konteyner volume'ni "ushlab" turadi, lekin fayllarga yozmaydi — arxiv izchil bo'ladi.
- Bitta kichik jadvalli baza ham ~4–5 MB bo'ladi: hajmning asosiy qismi Postgres'ning tizim jadvallari va jurnal fayllari, sizning bitta qatoringiz emas. Raqam aniq mos kelmaydi — Postgres versiyasiga va jurnal holatiga bog'liq.
12. Real ishda
- Har bir Postgres konteyneri — nomli volume bilan. Docker Compose fayllarida (33-qism)
volumes:bo'limi aynan shu. - Dasturlashda bind mount: kod papkasini konteynerga ulab, o'zgarishni darhol ko'rish; SQL migratsiya fayllarini berish.
- Zaxira: server'da volume arxivi yetarli emas —
pg_dump, avtomatik jadval, boshqa serverga nusxa va tiklash mashqi kerak. Bu 27 va 34-qismlardagi mavzular. - Intervyu savollari: "Volume va bind mount farqi?", "Konteyner o'chirilganda ma'lumot qayerga ketadi?", "Postgres'ni Docker'da ishlatsangiz, ma'lumotni qanday saqlaysiz?". Yaxshi javob: "nomli volume, to'g'ri yo'l, va
pg_dumpbilan tekshirilgan zaxira".
Xulosa
- Konteynerning yoziladigan qatlami konteyner bilan o'chadi — doimiy ma'lumot tashqarida bo'lishi kerak.
- Named volume — Docker boshqaradi, baza uchun eng yaxshi; bind mount — sizning papkangiz, fayl berish uchun; tmpfs — faqat RAM.
- PostgreSQL 18:
-v nom:/var/lib/postgresql(baza18/dockerichida); eski/datayo'li xato beradi. - Windows papkalari konteynerda
root 777bo'lib ko'rinadi — Linux ruxsatlari yo'q; baza uchun bind mount emas, volume. - Zaxira — to'xtatilgan konteynerdan yoki
pg_dumpbilan; tiklab ko'rilmagan zaxira — zaxira emas. docker volume rmso'ramaydi va qaytarilmaydi;prunebuyruqlari bilan ehtiyot bo'ling.
Keyingi dars: Nega ma'lumotlar bazasi — Docker tayyor; endi nega JSON fayl o'rniga baza kerakligini 10 ta parallel jarayon bilan o'lchab ko'ramiz.
Manbalar
- Docker hujjati — Volumes: https://docs.docker.com/engine/storage/volumes/
- Docker hujjati — Bind mounts: https://docs.docker.com/engine/storage/bind-mounts/
- Docker hujjati — tmpfs mounts: https://docs.docker.com/engine/storage/tmpfs/
- Docker hujjati — WSL best practices (fayllarni WSL fayl tizimida saqlash): https://docs.docker.com/desktop/features/wsl/best-practices/
- docker-library/postgres PR 1259 (18+ volume yo'li): https://github.com/docker-library/postgres/pull/1259
- PostgreSQL 18 hujjati — Creating a Database Cluster (ma'lumotlar katalogi ruxsatlari): https://www.postgresql.org/docs/18/creating-cluster.html
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!