IlmHamroh
JavaScript Full-stack/26-qism. SQL va PostgreSQL2/64-dars20 daqiqa
Mundarija (46)

Docker image, container va registry: asosiy buyruqlar

Qisqacha: Image β€” konteyner yasaladigan o'zgarmas shablon (dastur va uning fayllari), container β€” shu image'dan ishga tushirilgan nusxa. Image'lar registry'da saqlanadi, eng mashhuri β€” Docker Hub. Kundalik ish bir necha buyruq bilan bajariladi: docker pull (yuklash), docker run (ishga tushirish), docker ps (ro'yxat), docker logs (loglar), docker exec (ichida buyruq), docker stop va docker rm (to'xtatish va o'chirish).

Bu darsda

  • Image, container va registry farqini JavaScript'dagi klass va obyekt o'xshatishi bilan tushuntira olasiz.
  • postgres:18 image'ini tanlab, uni docker run bilan to'g'ri bayroqlar bilan ishga tushira olasiz.
  • docker ps, docker logs, docker exec, docker inspect bilan konteyner ichida nima bo'layotganini ko'rasiz.
  • Konteynerning hayot siklini (ishlaydi β†’ to'xtagan β†’ o'chirilgan) boshqarasiz.
  • -p va -e bilan bog'liq xavfsizlik tuzoqlarini bilasiz.

Oldin bilishingiz kerak: Konteyner nima va Docker'ni o'rnatish, process obyekti: argv, env, exit kodlari va signallar.

1. Nega bu kerak?

Oldingi darsda Docker'ni o'rnatdingiz va hello-world ni ishga tushirdingiz. U matn chiqardi va to'xtadi. Bizga esa boshqacha konteyner kerak: PostgreSQL 18 β€” fonda doim ishlab turadigan, port orqali ulanish qabul qiladigan, ma'lumotni saqlaydigan server.

Buning uchun bir nechta savolga javob kerak. Qaysi image? Konteynerni qanday nomlaymiz? Parolni qanday beramiz? Kompyuterdagi qaysi port konteynerga ulanadi? Server ishlayaptimi β€” loglarni qanday ko'ramiz? Bu darsning buyruqlari aynan shu savollarga javob.

Hayotiy o'xshatish: siz JavaScript'da klass yozgansiz. Klass β€” shablon, new bilan undan obyektlar yasaladi. Bitta klassdan istalgancha obyekt chiqadi, har birining o'z holati bor. Docker'da image β€” klass, container β€” new bilan yasalgan obyekt. Registry esa β€” klasslar saqlanadigan npm'ga o'xshash ombor.

2. Uch tushuncha

2.1 Image

Image β€” konteyner uchun o'zgarmas shablon: dastur, uning kutubxonalari, sozlamalari va qaysi buyruq bilan ishga tushishi. Image o'zgarmaydi. Konteyner ichida fayl o'zgarsa ham, image avvalgidek qoladi.

Image qatlamlardan (layers) iborat. Har qatlam β€” oldingisiga qo'shilgan fayllar. Masalan postgres:18: pastda Debian 13 fayllari, ustida PostgreSQL dasturi, eng ustida ishga tushirish skripti. Bir xil qatlamni bir nechta image bo'lishsa, u diskda bir marta saqlanadi.

2.2 Container

Container (konteyner) β€” image'dan yaratilgan va ishga tushirilgan nusxa. Image ustiga yupqa yoziladigan qatlam qo'shiladi β€” konteyner o'z o'zgarishlarini shu yerga yozadi. Bitta image'dan o'nta konteyner ishga tushirsangiz, har birining o'z yoziladigan qatlami bo'ladi.

2.3 Registry va teg

Registry (reestr) β€” image'lar saqlanadigan va tarqatiladigan server. Eng kattasi β€” Docker Hub (hub.docker.com). Kompaniyalar o'z yopiq registry'larini ham ishlatadi: GitHub Container Registry (ghcr.io), bulut provayderlarniki.

Image nomi ikki qismdan iborat β€” nom:teg:

  • postgres β€” repozitoriy nomi. Docker Hub'dagi postgres β€” rasmiy image (official image): uni Docker va PostgreSQL hamjamiyati birga tekshirib turadi.
  • 18 β€” teg (tag): versiya belgisi. postgres:18 β€” 18-versiyaning eng yangi tuzatishi. postgres:18.6 β€” aniq tuzatish versiyasi.

Teg yozilmasa, Docker latest deb hisoblaydi. postgres = postgres:latest. Bugun bu 18, bir yildan keyin 19 bo'lishi mumkin. Shuning uchun loyihada doim aniq teg yozing.

Uchalasining bog'lanishiga qarang: registry'dan image bir marta yuklanadi, undan esa bir nechta konteyner yasaladi:

flowchart LR
  R["Registry: Docker Hub"] -->|"docker pull"| I["Image: postgres:18"]
  I -->|"docker run"| C1["Konteyner 1"]
  I -->|"docker run"| C2["Konteyner 2"]
  I -->|"docker push"| R

Tekshirib ko'ring: Konteyner ichida rm -rf /usr/share/doc qilsangiz, shu image'dan yaratilgan yangi konteynerda bu papka bo'ladimi?

Javob

Bo'ladi. O'chirish konteynerning o'z yoziladigan qatlamida bo'ldi. Image o'zgarmas β€” undan yaratilgan har yangi konteyner toza holatdan boshlanadi. Xuddi klassdan yangi obyekt yaratganda eski obyektning o'zgarishlari o'tmagani kabi.

3. Image'lar bilan ishlash

3.1 docker pull β€” yuklab olish

bash
docker pull postgres:18

Bu buyruq image'ni registry'dan kompyuterga yuklaydi. Har qatlam alohida yuklanadi va ekranda o'z qatori bilan ko'rinadi. Image allaqachon bo'lsa, Docker faqat yangilangan qatlamlarni oladi. docker run ham image topilmasa, uni o'zi yuklaydi β€” shuning uchun pull ni alohida yozish shart emas, lekin oldindan yuklab qo'yish qulay.

3.2 docker images β€” kompyuterdagi image'lar

bash
docker images postgres:18

Natija:

text
IMAGE         ID             DISK USAGE   CONTENT SIZE   EXTRA
postgres:18   edb0c08dc33b        650MB          169MB        

Ustunlarni o'qiymiz:

  • ID β€” image'ning qisqa identifikatori (to'liq ID β€” 64 belgili hash).
  • CONTENT SIZE β€” 169 MB: registry'dan yuklanadigan siqilgan hajm.
  • DISK USAGE β€” 650 MB: diskda ochilgan holatdagi hajm.

Demak, internet orqali 169 MB keladi, lekin diskda 650 MB joy kerak. Telefon tarmog'idan yuklasangiz shuni hisobga oling.

3.3 docker image inspect β€” image ichiga qarash

inspect image haqida hamma ma'lumotni JSON ko'rinishida beradi. --format bilan faqat kerakli maydonlarni olamiz. Shablon uzun, shuning uchun uni avval F o'zgaruvchisiga yig'amiz (Git Bash'da yozing; += β€” satr oxiriga qo'shish):

bash
F='{{.Id}} {{.Created}} {{.Size}} '
F+='{{json .Config.Volumes}} {{json .Config.Env}}'
docker image inspect postgres:18 --format "$F"

Natija bitta uzun qator. Undan uchta bo'lakni qidiring: sana, /var/lib/postgresql va PG_VERSION.

text
sha256:edb0c08dc33befd0262ab3b5cf1c4f3f8cfd8b09e88c05b45adee29d6761ddb6 2026-10-21T00:37:01.146225564Z 644157181 {"/var/lib/postgresql":{}} ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/18/bin","GOSU_VERSION=1.19","LANG=en_US.utf8","PG_MAJOR=18","PG_VERSION=18.6-1.pgdg13+2","PGDATA=/var/lib/postgresql/18/docker"]

Uchta muhim narsa:

  • 2026-10-21 β€” image yaratilgan sana. Rasmiy image'lar xavfsizlik tuzatishlari bilan tez-tez qayta yig'iladi β€” postgres:18 tegi ostidagi image o'zgarib turadi.
  • {"/var/lib/postgresql":{}} β€” image'da VOLUME e'lon qilingan. Bu ma'lumot saqlanadigan papka. Uning oqibatini Β«Yashirin qoldiq: anonim volumeΒ» bo'limida ko'ramiz, batafsil β€” keyingi darsda.
  • PG_VERSION=18.6-1.pgdg13+2 β€” ichidagi aniq PostgreSQL versiyasi. PGDATA β€” baza fayllari yo'li.

4. Konteynerni ishga tushirish

4.1 docker run va uning bayroqlari

PostgreSQL 18 konteynerini ishga tushiramiz:

bash
docker run -d --name kanon26-demo \
  -e POSTGRES_PASSWORD=namuna_parol \
  -p 127.0.0.1:5498:5432 \
  postgres:18

Natija:

text
3eb104716aea259b121d657ab3770bea0adac20e9e4ab28c749179794f38728e

Bu β€” yangi konteynerning to'liq ID'si. Konteynerlarimiz nomini kanon26- bilan boshladik β€” kompyuterdagi boshqa konteynerlar bilan adashmaslik va keyin faqat o'zimiznikini o'chirish uchun. Siz o'zingizga qulay nom bering.

Har bayroq nima qiladi:

Bayroq Ma'nosi Bu misolda
-d detached: fonda ishlaydi, terminal bo'shaydi server fonda
--name konteynerga nom kanon26-demo
-e muhit o'zgaruvchisi superuser paroli
-p port: host:konteyner 5498 β†’ 5432
--rm to'xtaganda o'zini o'chiradi (bu yerda yo'q)

-e β€” process obyekti darsidagi process.env ning o'zi: konteyner ichidagi jarayon uni muhit o'zgaruvchisi sifatida o'qiydi. postgres image'i POSTGRES_PASSWORD ni o'qib, birinchi ishga tushishda superuser parolini o'rnatadi.

--rm ni bu yerda ataylab bermadik: server konteyneri to'xtaganda o'chib ketmasin. --rm bir martalik buyruqlar uchun qulay β€” hello-world dagi kabi.

4.2 -p: port yo'naltirish

Konteynerning o'z tarmoq namespace'i bor. Uning 5432-porti tashqaridan ko'rinmaydi. -p bayrog'i host'dagi portni konteyner portiga ulaydi:

flowchart LR
  A["Ilova yoki psql"] -->|"127.0.0.1:5498"| H["Host: Windows"]
  H -->|"5432"| C["Konteyner: Postgres"]

-p 127.0.0.1:5498:5432 uch qismdan iborat: qaysi manzilda tinglash (127.0.0.1), host porti (5498), konteyner porti (5432). Host porti ixtiyoriy β€” kompyuterda Postgres allaqachon 5432 da ishlasa, boshqasini tanlaysiz. Konteyner porti esa image'ga bog'liq: Postgres doim 5432 da tinglaydi.

127.0.0.1 ni yozish muhim β€” bu haqda Β«Hujumchi nigohiΒ» bo'limida.

4.3 Parolsiz ishga tushirsangiz

Parol bermasak nima bo'ladi?

bash
docker run --rm --name kanon26-parolsiz postgres:18

Natija:

text
Error: Database is uninitialized and superuser password is not specified.
       You must specify POSTGRES_PASSWORD to a non-empty value for the
       superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".

       You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
       connections without a password. This is *not* recommended.

       See PostgreSQL documentation about "trust":
       https://www.postgresql.org/docs/current/auth-trust.html

Tarjimasi: "Baza hali yaratilmagan va superuser paroli ko'rsatilmagan. POSTGRES_PASSWORD ga bo'sh bo'lmagan qiymat bering. Yoki POSTGRES_HOST_AUTH_METHOD=trust bilan hamma ulanishga parolsiz ruxsat bering β€” bu tavsiya etilmaydi."

Image sizni parolsiz bazadan himoya qildi. trust (ishonch) usulini kursda faqat o'z kompyuterimizda, 127.0.0.1 bilan ishlatamiz. Uni PostgreSQL o'rnatish va ulanish darsida ko'rasiz.

5. Konteynerni kuzatish

5.1 docker ps β€” ishlayotganlar ro'yxati

bash
docker ps --filter name=kanon26

Natija:

text
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS                      NAMES
3eb104716aea   postgres:18   "docker-entrypoint.s…"   3 seconds ago   Up 2 seconds   127.0.0.1:5498->5432/tcp   kanon26-demo

--filter name=kanon26 β€” faqat nomida shu so'z bor konteynerlar. Ustunlar:

  • CONTAINER ID β€” to'liq ID'ning boshidagi 12 belgi. Buyruqlarda nom o'rniga shuni ham yozsa bo'ladi.
  • COMMAND β€” konteyner ishga tushirgan buyruq (docker-entrypoint.sh, qisqartirilgan).
  • STATUS β€” Up 2 seconds: 2 soniyadan beri ishlayapti.
  • PORTS β€” 127.0.0.1:5498->5432/tcp: host'ning 5498-porti konteynerning 5432-portiga.

docker ps faqat ishlayotgan konteynerlarni ko'rsatadi. docker ps -a β€” to'xtaganlarini ham.

5.2 docker logs β€” konteyner nima deyapti

Konteyner ichidagi asosiy jarayonning chiqishi Docker'da saqlanadi. Oxirgi 8 qatorni o'qiymiz β€” eng muhimi ro'yxatning oxirgi qatori:

bash
docker logs --tail 8 kanon26-demo

Natija:

text
PostgreSQL init process complete; ready for start up.

2026-10-24 03:02:03.203 UTC [1] LOG:  starting PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
2026-10-24 03:02:03.204 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2026-10-24 03:02:03.204 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2026-10-24 03:02:03.218 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2026-10-24 03:02:03.236 UTC [79] LOG:  database system was shut down at 2026-10-24 03:02:03 UTC
2026-10-24 03:02:03.247 UTC [1] LOG:  database system is ready to accept connections

Qatorlarni tarjima qilamiz:

  • init process complete β€” baza birinchi marta yaratildi (parol o'rnatildi).
  • starting PostgreSQL 18.6 β€” server ishga tushyapti. [1] β€” PID 1, konteynerdagi asosiy jarayon.
  • listening on ... port 5432 β€” konteyner ichida 5432-portda kutyapti. 0.0.0.0 β€” konteynerning hamma tarmoq manzillarida.
  • ready to accept connections β€” tayyor, ulanish mumkin. Ilova ulanmasa, birinchi navbatda shu qatorni qidiring.

Vaqt UTC da β€” konteyner ichida vaqt zonasi sozlanmagan. Toshkent vaqti 5 soat oldinda (03:02 UTC = 08:02 Toshkent).

docker logs -f kanon26-demo β€” follow rejimi: yangi qatorlar paydo bo'lishi bilan ekranga chiqadi, xuddi tail -f kabi. Chiqish uchun Ctrl+C β€” bu faqat kuzatishni to'xtatadi, konteyner ishlashda davom etadi.

5.3 docker exec β€” ichida buyruq bajarish

Konteyner ichida yana bitta buyruq ishga tushiramiz β€” Postgres versiyasini so'raymiz. psql β€” PostgreSQL'ning terminal mijozi, u image ichida bor:

bash
docker exec kanon26-demo psql -U postgres -c "select version();"

Natija:

text
                                                      version                                                       
--------------------------------------------------------------------------------------------------------------------
 PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
(1 row)

select version(); β€” SQL so'rovi, SQL'ni bu qismda bosqichma-bosqich o'rganasiz. Hozir faqat natijaga qarang: konteyner ichida haqiqatan PostgreSQL 18.6 ishlayapti.

Parol so'ralmadi. Sababi: konteyner ichidan ulanish image sozlamasida ishonchli deb belgilangan, parol faqat tashqaridan ulanganda so'raladi. Buni PostgreSQL o'rnatish va ulanish darsida haqiqiy sozlama fayli bilan ko'ramiz.

Interaktiv ish uchun -it bayroqlari bor:

bash
docker exec -it kanon26-demo psql -U postgres

-i β€” kirishni ochiq tutadi, -t β€” terminal ajratadi. Natijada konteyner ichidagi psql bilan bevosita gaplashasiz: so'rov yozasiz, javob olasiz. \q β€” chiqish. Shu usul bilan konteynerga shell orqali ham kirish mumkin: docker exec -it kanon26-demo bash. Interaktiv sessiyani biz kursda yozib ko'rsata olmaymiz β€” o'zingiz sinang (4-mashq).

5.4 docker inspect β€” konteyner haqida hammasi

inspect konteyner haqida yuzlab maydonli JSON beradi. Eski qo'llanmalarda konteyner IP manzilini shunday olish yoziladi:

bash
F='{{.State.Status}} {{.NetworkSettings.IPAddress}} '
F+='{{json .HostConfig.PortBindings}} {{json .Mounts}}'
docker inspect kanon26-demo --format "$F"

Docker 29 da bu buyruq ishlamaydi:

text
template parsing error: template: :1:36: executing "" at <.NetworkSettings.IPAddress>: map has no entry for key "IPAddress"

Tarjimasi: "shablonni bajarishda xato: NetworkSettings ichida IPAddress kaliti yo'q". Docker yangi versiyalarda bu eski maydonni olib tashladi. Endi IP har tarmoq ichida alohida saqlanadi:

bash
F='{{.State.Status}} {{range $n, $v := .NetworkSettings.Networks}}'
F+='{{$n}}={{$v.IPAddress}}{{end}} {{json .HostConfig.PortBindings}}'
docker inspect kanon26-demo --format "$F"

{{range ...}}{{end}} β€” shablon ichidagi sikl: har tarmoq uchun nom=IP yozadi.

Natija:

text
running bridge=172.17.0.2 {"5432/tcp":[{"HostIp":"127.0.0.1","HostPort":"5498"}]}

Konteyner ishlayapti, bridge tarmog'ida 172.17.0.2 manzili bor, port bog'lanishi ham ko'rinib turibdi. bridge β€” Docker'ning sukut tarmog'i. Windows'da bu IP'ga host'dan to'g'ridan ulanib bo'lmaydi β€” u WSL2 VM ichida. Shuning uchun -p kerak.

Tekshirib ko'ring: docker logs -f ni Ctrl+C bilan to'xtatdingiz. Postgres ham to'xtadimi?

Javob

Yo'q. logs -f β€” alohida mijoz buyrug'i, u faqat loglarni kuzatardi. Ctrl+C shu kuzatishni uzdi. Konteyner fonda (-d) ishlashda davom etadi. To'xtatish uchun docker stop kerak.

6. Hayot sikli: to'xtatish va o'chirish

6.1 Holatlar

Konteyner bir nechta holatdan o'tadi. Strelkalar ustida β€” o'tkazadigan buyruq:

stateDiagram-v2
  [*] --> Running: docker run
  Running --> Exited: docker stop
  Exited --> Running: docker start
  Exited --> [*]: docker rm
  Running --> [*]: docker rm -f

6.2 stop va start

bash
docker stop kanon26-demo
docker ps -a --filter name=kanon26

Natija:

text
kanon26-demo
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS                              PORTS     NAMES
3eb104716aea   postgres:18   "docker-entrypoint.s…"   8 seconds ago   Exited (0) Less than a second ago             kanon26-demo

Exited (0) β€” konteyner to'xtagan, asosiy jarayon exit kod 0 bilan tugagan, ya'ni xatosiz. Exit kodlarni process obyekti darsidan bilasiz. docker stop avval SIGTERM signalini yuboradi β€” Postgres uni ushlab, ishini toza yakunlaydi. Sukut bo'yicha 10 soniyada tugamasa, Docker SIGKILL yuboradi.

To'xtagan konteyner o'chmagan: u diskda turibdi, ichidagi o'zgarishlar bilan. docker start kanon26-demo uni xuddi shu holatda qayta yoqadi.

6.3 rm β€” o'chirish

Ishlab turgan konteynerni o'chirishga urinamiz (u start dan keyin yana ishlayapti):

bash
docker rm kanon26-demo

Natija:

text
Error response from daemon: cannot remove container "kanon26-demo": container is running: stop the container before removing or force remove

Tarjimasi: "daemon javobi: konteynerni o'chirib bo'lmaydi β€” u ishlayapti. Avval to'xtating yoki majburan o'chiring". Docker sizni tasodifiy o'chirishdan himoya qildi. Majburan:

bash
docker rm -f kanon26-demo
docker ps -a --filter name=kanon26

Natija:

text
kanon26-demo
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Konteyner ro'yxatdan yo'qoldi. Lekin hammasi o'chdimi?

6.4 Yashirin qoldiq: anonim volume

Β«docker image inspect β€” image ichiga qarashΒ» bo'limida image'da VOLUME e'lon qilinganini ko'rdik. Biz -v bermadik β€” shunda Docker konteyner uchun anonim volume (nomsiz saqlash joyi) yaratadi va bazani o'sha yerga yozadi. docker rm uni o'chirmaydi. O'chirishdan oldin uning nomini VOL o'zgaruvchisiga saqlab qo'ygan edik ({{range .Mounts}}{{.Name}}{{end}} shabloni bilan):

bash
VOL=422802a28974133079d0f1ed22399ba267540c7477e2a007679dc4926bf11207
docker volume ls --filter name=$VOL

Natija:

text
DRIVER    VOLUME NAME
local     422802a28974133079d0f1ed22399ba267540c7477e2a007679dc4926bf11207

Konteyner yo'q, uning bazasi esa diskda qoldi. Har docker run postgres:18 shunday iz qoldiradi va ular sekin-asta diskni to'ldiradi. Ikki yechim bor: docker rm -v (konteyner bilan birga uning anonim volume'larini ham o'chiradi) yoki volume'ga nom berish β€” buni keyingi darsda o'rganasiz. Biz qoldiqni qo'lda o'chirdik:

bash
docker volume rm $VOL

Diqqat: docker volume rm ni ehtiyot bilan ishlating β€” volume ichidagi ma'lumotni qaytarib bo'lmaydi. Bu yerda o'chirdik, chunki bu sinov bazasi edi.

7. tag va rmi

7.1 docker tag β€” image'ga yangi nom

bash
docker tag postgres:18 kanon26/postgres:dars
docker images kanon26/postgres

Natija:

text
IMAGE                   ID             DISK USAGE   CONTENT SIZE   EXTRA
kanon26/postgres:dars   edb0c08dc33b        650MB          169MB        

ID bir xil β€” edb0c08dc33b. tag nusxa yaratmaydi, xuddi shu image'ga ikkinchi nom beradi. Disk joyi ikki baravar oshmaydi. Teg image'ni registry'ga yuklashda kerak: docker push nomning birinchi qismiga qarab qaysi registry va qaysi hisobga yuklashni biladi (masalan ghcr.io/login/ilova:1.0). Push uchun registry'da hisob kerak β€” buni deploy qismlarida qilasiz.

7.2 docker rmi β€” image'ni o'chirish

bash
docker rmi kanon26/postgres:dars

Natija:

text
Untagged: kanon26/postgres:dars

Untagged β€” faqat nom olib tashlandi. Image'ning o'zi postgres:18 nomi bilan joyida qoldi. Image oxirgi nomi ham olib tashlanganda haqiqatan o'chadi. Undan yaratilgan konteyner (hatto to'xtagan) bo'lsa, Docker image'ni o'chirishga ruxsat bermaydi.

Tekshirib ko'ring: docker rm va docker rmi farqi nima?

Javob

docker rm β€” konteynerni o'chiradi (obyektni). docker rmi β€” imageni o'chiradi (klassni); i β€” image. Klassni o'chirishdan oldin undan yasalgan obyektlarni o'chirish kerak β€” Docker'da ham tartib shunday.

8. Hujumchi nigohi

8.1 Port hammaga ochiq

Ko'p qo'llanmalarda shunday yoziladi: -p 5432:5432. Manzil yo'q β€” demak Docker host'ning hamma tarmoq manzillarida tinglaydi (0.0.0.0). Noutbukingiz kafedagi Wi-Fi'da bo'lsa, shu tarmoqdagi istalgan qurilma 5432 ga ulanishga urinishi mumkin. Server'da esa butun internet.

Hujumchilar internetni avtomatik skanerlab, ochiq 5432 portlarni qidiradi va postgres foydalanuvchisiga ommabop parollarni tanlab ko'radi. trust bilan ochilgan bazaga esa parolsiz kiradi.

Linux server'da yana bir tuzoq bor. Bu Docker hujjatida yozilgan, biz uni sinamadik. Docker port ochish uchun tizim qoidalarini o'zi qo'shadi. Shuning uchun ufw kabi firewall'da porti yopiq deb turgan bo'lsangiz ham, -p bilan ochilgan port tashqaridan ko'rinishi mumkin.

Himoya: lokal ish uchun doim -p 127.0.0.1:5498:5432. Shunda port faqat shu kompyuterning o'zidan ochiladi.

8.2 Parol konteyner muhitida ochiq

-e bilan berilgan parol qayerda saqlanadi? Konteyner muhitini ko'ramiz:

bash
docker exec kanon26-demo env

Natija:

text
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/18/bin
HOSTNAME=3eb104716aea
POSTGRES_PASSWORD=namuna_parol
GOSU_VERSION=1.19
LANG=en_US.utf8
PG_MAJOR=18
PG_VERSION=18.6-1.pgdg13+2
PGDATA=/var/lib/postgresql/18/docker
HOME=/root

POSTGRES_PASSWORD=namuna_parol β€” ochiq matnda. docker inspect ham uni ko'rsatadi. Docker'ga kira oladigan har kim parolni o'qiy oladi. Qo'shimcha: buyruqni terminalda yozsangiz, parol shell tarixiga ham tushadi.

Qoidalar:

  • Haqiqiy parolni buyruqqa yoki kodga yozmang. Docker'da buning uchun --env-file (fayldan o'qish, fayl git'ga tushmaydi) va server'da secrets mexanizmi bor β€” deploy qismlarida ko'rasiz.
  • Docker'ga kirish huquqi = kompyuterda root huquqi. Docker hujjati ham shuni aytadi: docker guruhidagi foydalanuvchi butun tizimni boshqara oladi.
  • Kursdagi namuna_parol β€” faqat bir martalik, lokal sinov uchun.

8.3 Begona image

docker run birov/postgres-tez β€” noma'lum muallifning image'i. Ichida nima borligini bilmaysiz: kriptovalyuta qazuvchi dastur ham bo'lishi mumkin. Rasmiy image'lar (postgres, node, redis β€” Docker Hub'da "Docker Official Image" belgisi bilan) yoki ishonchli kompaniyalarnikini ishlating. Aniq teg yozing, latest emas.

9. SQL qadami: bu darsda nima qildik

Bu darsda SQL loyihasiga hech narsa qo'shilmaydi va commit yo'q. Biz faqat PostgreSQL 18 konteynerini ishga tushirib, ichida haqiqatan 18.6 ishlayotganini tekshirdik va keyin o'chirdik.

Asosiy, doimiy konteyner β€” vazifalar bazasi bilan β€” PostgreSQL o'rnatish va ulanish darsida yaratiladi. U yerda nomli volume, 127.0.0.1 porti va ulanish satri bo'ladi. Ungacha bu darsdagi buyruqlarni erkin sinang: konteyner yarating, o'chiring, qaytadan yarating.

10. Ko'p uchraydigan xatolar

10.1 Bayroqdagi imlo xatosi

Biz ataylab --name o'rniga --naem yozdik:

bash
docker run --naem test postgres:18

Natija:

text
unknown flag: --naem

Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run 'docker run --help' for more information

Tarjimasi: "noma'lum bayroq". Docker bu holatda 125 exit kodi bilan chiqadi β€” bu konteyner emas, Docker'ning o'zi xato bergani belgisi.

10.2 Bayroqni image nomidan keyin yozish

bash
docker run postgres:18 -d

Buyruqning umumiy shakliga qarang: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]. Image nomidan keyin yozilgan hamma narsa β€” konteyner ichidagi buyruq uchun. Bu misolda -d Docker'ga emas, konteyner ichidagi Postgres'ga argument bo'lib boradi va konteyner fonda ishlamaydi. Natijasini biz yozib olmadik β€” qoida buyruq shaklidan kelib chiqadi. Docker'ning bayroqlari doim image nomidan oldin.

10.3 Ishlab turgan konteynerni o'chirish

container is running: stop the container before removing or force remove β€” yuqorida ko'rdik. Yechim: docker stop, keyin docker rm, yoki docker rm -f.

10.4 Eski qo'llanmadagi format

map has no entry for key "IPAddress" β€” Docker 29 dagi o'zgarish. Internetdagi eski maqolalar va AI javoblari ham shu formatni berishi mumkin. Yechim: .NetworkSettings.Networks orqali (Β«docker inspect β€” konteyner haqida hammasiΒ» bo'limida).

10.5 Nom band

Bir xil --name bilan ikkinchi konteyner yaratib bo'lmaydi β€” eski konteyner to'xtagan bo'lsa ham. Docker nom band ekanini aytadi. Yechim: avval docker rm eski_nom yoki boshqa nom. (Bu xatoni biz yozib olmadik, xabar matni versiyaga qarab farq qiladi.)

11. Mashqlar

Mashqlar kurs/mashqlar/26/02-image-container/ da.

1-mashq (oson): bayroqni toping

  • Konteynerni fonda ishga tushirish β€” docker run .
  • Konteynerga nom berish β€” .
  • Muhit o'zgaruvchisi berish β€” .
  • Port bog'lash β€” .
  • Ishi tugagach o'zini o'chirish β€” .
  • To'xtagan konteynerlarni ham ko'rsatish β€” docker ps .
Yechim

-d β€” detached (fonda). --name β€” nom. -e β€” environment (muhit). -p β€” publish (portni nashr qilish). --rm β€” remove (o'chirish). ps -a β€” all (hammasi). Bayroqlarning inglizcha asli eslab qolishga yordam beradi.

2-mashq (o'rta): buyruqlar tartibi

Quyidagi buyruqlar aralashib ketgan. Ularni to'g'ri tartibda yozing β€” pg-mashq konteynerini yaratib, ishlayotganini tekshirib, to'liq tozalash uchun:

  • docker rm -v pg-mashq
  • docker logs pg-mashq
  • docker run -d --name pg-mashq -e POSTGRES_PASSWORD=mashq_parol -p 127.0.0.1:5496:5432 postgres:18
  • docker stop pg-mashq
  • docker exec pg-mashq psql -U postgres -c "select 1;"
Yechim
  1. docker run -d --name pg-mashq ... β€” yaratish va ishga tushirish.
  2. docker logs pg-mashq β€” ready to accept connections ni kutish.
  3. docker exec pg-mashq psql -U postgres -c "select 1;" β€” bazaga so'rov.
  4. docker stop pg-mashq β€” toza to'xtatish (SIGTERM).
  5. docker rm -v pg-mashq β€” konteyner va uning anonim volume'ini o'chirish.

-v ni unutsangiz, anonim volume diskda qoladi. logs ni exec dan oldin tekshirish muhim: server hali tayyor bo'lmasa, psql ulana olmaydi.

3-mashq (qiyin): PORTS ustunini tahlil qilish

docker ps dagi PORTS qiymatini tekshiradigan portniTahlilQil(matn) funksiyasini yozing. "127.0.0.1:5498->5432/tcp" dan obyekt qaytarsin: { manzil, hostPort, konteynerPort, protokol, hammagaOchiq }. hammagaOchiq β€” manzil 0.0.0.0 yoki :: bo'lsa true. Format mos kelmasa β€” null.

Ishora: muntazam ifoda (RegExp) bilan uch qismni ajrating: manzil : gacha (oxirgi : dan oldingi hamma narsa β€” IPv6'da ham : bor), keyin port, ->, port, /, protokol. Portni Number() bilan songa aylantiring.

Yechim
js
const PORT_QOLIPI = /^(.+):(\d+)->(\d+)\/(tcp|udp)$/;

function portniTahlilQil(matn) {
  const m = PORT_QOLIPI.exec(matn);
  if (!m) return null;
  const [, manzil, host, ichki, protokol] = m;
  return {
    manzil,
    hostPort: Number(host),
    konteynerPort: Number(ichki),
    protokol,
    hammagaOchiq: manzil === "0.0.0.0" || manzil === "::",
  };
}

console.log(portniTahlilQil("127.0.0.1:5498->5432/tcp"));
console.log(portniTahlilQil("0.0.0.0:5432->5432/tcp"));
console.log(portniTahlilQil(":::5432->5432/tcp"));
console.log(portniTahlilQil("5432/tcp"));

Konsolda:

text
{
  manzil: '127.0.0.1',
  hostPort: 5498,
  konteynerPort: 5432,
  protokol: 'tcp',
  hammagaOchiq: false
}
{
  manzil: '0.0.0.0',
  hostPort: 5432,
  konteynerPort: 5432,
  protokol: 'tcp',
  hammagaOchiq: true
}
{
  manzil: '::',
  hostPort: 5432,
  konteynerPort: 5432,
  protokol: 'tcp',
  hammagaOchiq: true
}
null

(.+) ochko'z (greedy) β€” u imkon qadar ko'p belgi oladi. Shuning uchun :::5432 da manzil :: bo'ladi β€” oxirgi : dan oldingi qism. "5432/tcp" β€” port host'ga bog'lanmagan holat (-p siz, image faqat portni e'lon qilgan): bunday konteynerga host'dan ulanib bo'lmaydi, funksiya null qaytaradi. Shu funksiya bilan "qaysi konteyner porti hammaga ochiq?" degan tekshiruv skriptini yozish mumkin.

4-mashq: SQL qadami β€” o'z Postgres konteyneringiz

  1. 2-mashqdagi pg-mashq konteynerini yarating.
  2. docker logs pg-mashq da ready to accept connections qatorini toping.
  3. docker exec -it pg-mashq psql -U postgres bilan ichiga kiring va select version(); yozing. \q bilan chiqing.
  4. docker inspect bilan konteyner IP'sini to'g'ri format bilan oling.
  5. Konteynerni -v bilan o'chiring va docker volume ls da qoldiq yo'qligini tekshiring.
Yechim
  1. Loglar oxirida database system is ready to accept connections bo'ladi (darsdagi chiqishdagidek, vaqtlar boshqa).
  2. PostgreSQL 18.x (Debian ...) qatori β€” x sizda yuklagan paytdagi tuzatish raqami.
  3. docker inspect pg-mashq --format '{{range $n, $v := .NetworkSettings.Networks}}{{$v.IPAddress}}{{end}}' β€” odatda 172.17.0.x.
  4. docker stop pg-mashq va docker rm -v pg-mashq. docker volume ls da 64 belgili nomsiz volume qolmagan bo'lsa β€” to'g'ri. Qolgan bo'lsa, -v siz o'chirgansiz: docker volume rm <nom> bilan tozalang.

12. Real ishda

  • Har kuni: docker ps, docker logs -f, docker exec -it ... sh β€” server'dagi muammoni tekshirishning birinchi qadami. "Sayt ishlamayapti" β€” avval qaysi konteyner Exited, loglarida nima bor.
  • Teg siyosati: jamoalar image tegini aniq yozadi (postgres:18.6), ba'zan digest bilan (postgres@sha256:...) β€” shunda image hech qachon "o'zidan" o'zgarmaydi.
  • Xavfsizlik auditi: ochiq 0.0.0.0:5432, latest teg, kodga yozilgan parol β€” audit hisobotlarida birinchi topiladigan muammolar.
  • Intervyu savollari: "Image va container farqi?", "docker stop va docker kill farqi?" (SIGTERM va SIGKILL), "-p 5432:5432 nimasi xavfli?", "Konteyner o'chirilganda ma'lumot qayerga ketadi?" β€” oxirgisiga javob keyingi darsda.

Xulosa

  • Image β€” o'zgarmas shablon (klass), container β€” undan ishga tushirilgan nusxa (obyekt), registry β€” image'lar ombori (Docker Hub).
  • nom:teg β€” doim aniq teg; teg yo'q bo'lsa latest olinadi.
  • docker run -d --name ... -e ... -p 127.0.0.1:HOST:KONTEYNER image β€” server konteynerining asosiy shakli.
  • ps, logs, exec, inspect β€” kuzatish; stop, start, rm, rm -f β€” hayot sikli; tag, rmi β€” image nomlari.
  • postgres image'i -v siz anonim volume qoldiradi β€” docker rm -v yoki nomli volume.
  • -e dagi parol env va inspect da ochiq ko'rinadi; port faqat 127.0.0.1 ga.

Keyingi dars: Volume va bind mount: ma'lumotni saqlash β€” konteyner o'chirilganda bazangiz yo'qolmasligi uchun nomli volume, bind mount va zaxira.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Docker image, container va registry: asosiy buyruqlar β€” IlmHamroh