07 β Konteyner bilan ishlash¶
β¬ οΈ Oldingi: 06 β Docker nima: konteynerlar Β· π README Β· Keyingi: 08 β Dockerfile: o'z image'ingiz β‘οΈ
Bu bobda:
docker run'ni chuqur o'rganamiz β-d(fonda),-it(interaktiv),--rm(chiqqach o'chir),--name,-p host:konteyner(port),-e KEY=val(environment),-v(volume) va--restartbayroqlari; konteynerlarnips/logs/exec/stop/start/restart/rm/inspect/statsbilan boshqarish; image'larnipull/images/rmi/prunebilan boshqarish; konteyner hayot sikli (created β running β stopped β removed); va amaliyotdanginxhamdarediskonteynerlarini ishga tushirib, log ko'rib, ichiga kirib, to'xtatib, o'chirib chiqamiz.
Muammo: image bor, endi nima?¶
Oldingi bobda ko'rdik: image β bu ilovangizning "muzlatilgan surati" (kod + kutubxonalar + sozlamalar), container (konteyner) esa β shu image'dan tug'ilgan, ishlab turgan tirik nusxa. docker run nginx deb yozganingizda Docker image'dan konteyner yaratadi va ishga tushiradi.
Lekin amaliyotda savollar paydo bo'ladi: konteyner fonda ishlashini qanday qilaman? Brauzerdan unga qanday kiraman? Ishlab turgan konteyner ichida nima bo'lyapti β qanday ko'raman? To'xtatib, keyin yana ishga tushira olamanmi? Bu bob aynan shu kundalik ishlarni β konteynerni ishga tushirish, kuzatish va boshqarishni o'rgatadi. Bob oxirida docker run bayroqlarini yoddan bilasiz va konteynerni xuddi alohida kichik kompyuterdek boshqara olasiz.
βΉοΈ Bu bobdagi deyarli barcha buyruqlarni o'zingiz terib ko'ring. Docker o'rnatilgan bo'lishi kerak (06-bobga qarang). Misollar uchun internet kerak β birinchi marta
nginxvaredisimage'lari yuklab olinadi.
docker run β eng muhim buyruq¶
docker run β Docker'da eng ko'p ishlatiladigan buyruq. U bitta qatorda ikki ish qiladi: image'dan yangi konteyner yaratadi va uni ishga tushiradi. Umumiy tartibi shunday:
Diqqat: bayroqlar image nomidan oldin keladi. Image nomidan keyin yozilgan narsa β konteyner ichida bajariladigan buyruq deb qabul qilinadi.
Mana eng tipik misol β nginx web-serverni fonda, 8080-portda ishga tushirish. Quyidagi diagramma har bir bayroqni alohida ochib beradi:
Endi har bir bayroqni navbat bilan ko'rib chiqamiz.
-d β fonda ishlatish (detached)¶
-d (detached, "ajratilgan") konteynerni fonda ishga tushiradi va sizga konteyner ID'sini qaytarib, terminalni darrov bo'shatadi:
-d'siz konteyner oldinda (foreground) ishlaydi va uning chiqishi terminalingizni egallaydi β nginx to'xtamaguncha kursor qaytmaydi.
β οΈ Tez-tez xato: terminal "qotib qoladi". Ko'pchilik
docker run nginxdeb-d'siz yozadi, keyin terminal javob bermay qolganidan hayron bo'ladi. Sabab β konteyner oldinda ishlayapti. To'xtatish uchunCtrl+Cbosing, keyin-dbilan qayta ishga tushiring. Web-server, ma'lumotlar bazasi kabi uzoq ishlaydigan xizmatlar deyarli har doim-dbilan ishga tushiriladi.
-p host:konteyner β portni chiqarish¶
Konteyner ichidagi xizmat o'z portida (masalan nginx 80-portda) tinglaydi, lekin bu port konteyner ichida qamalgan β tashqaridan ko'rinmaydi. -p bayrog'i host (kompyuter/server) portini konteyner portiga bog'laydi:
Bu degani: host'ning 8080-portiga kelgan har bir so'rov konteynerning 80-portiga uzatiladi. Endi brauzerda http://localhost:8080 ochsangiz, nginx'ning sahifasini ko'rasiz.
π Format:
-p host:konteyner. Chap raqam β tashqaridan kiriladigan host porti, o'ng raqam β konteyner ichidagi port. Bularni adashtirmang:-p 8080:80to'g'ri,-p 80:8080esa boshqa narsa.-pumuman bo'lmasa, konteyner porti tashqaridan ko'rinmaydi (boshqa konteynerlar bilan ichki tarmoq orqali gaplasha oladi, lekin host'dan kira olmaysiz).
--name β qulay nom berish¶
Nom bermasangiz, Docker konteynerga tasodifiy nom (masalan nostalgic_turing) va uzun ID beradi. Keyingi buyruqlarda shu ID/nomni yozish noqulay. --name bilan o'zingiz tushunadigan nom bering:
Endi konteynerga docker logs web, docker stop web deb murojaat qila olasiz.
β οΈ Tez-tez xato: "nom band". Agar
webnomli konteyner allaqachon mavjud bo'lsa (hatto to'xtagan bo'lsa ham), yangi konteynerni shu nom bilan yarata olmaysiz:Conflict. The container name "/web" is already in use. Yechim β eski konteynerni o'chiring (docker rm web) yoki boshqa nom tanlang.
-e KEY=val β environment o'zgaruvchi¶
Ko'p image'lar o'z sozlamalarini environment o'zgaruvchilari (muhit o'zgaruvchilari) orqali oladi. Masalan PostgreSQL parolni POSTGRES_PASSWORD orqali oladi:
Bir nechta o'zgaruvchi uchun -e'ni qayta-qayta yozing. Bu β parol, port, til kabi sozlamalarni image'ni o'zgartirmasdan berishning standart usuli.
-v β volume (ma'lumotni saqlash, qisqacha)¶
Konteyner o'chsa, uning ichidagi yozilgan ma'lumot yo'qoladi. Ma'lumotni saqlab qolish uchun -v bilan volume (host'dagi doimiy joy) ulanadi:
docker run -d --name db \
-e POSTGRES_PASSWORD=maxfiy \
-v todo_data:/var/lib/postgresql/data \
postgres:17-alpine
Bu yerda todo_data nomli volume konteyner ichidagi ma'lumotlar papkasiga ulandi β endi konteyner o'chsa ham, ma'lumot volume'da qoladi.
π‘ Volume va Docker tarmog'ini chuqur β 10-bobda (Volume va Docker tarmog'i) ko'ramiz. Hozircha
-v nom:/yo'lformatini bilib qo'ying β ma'lumotlar bazasi konteynerlari uchun u shart.
--rm β chiqqach avtomatik o'chirish¶
Vaqtinchalik, bir martalik konteynerlar (masalan biror buyruqni sinab ko'rish) uchun --rm qulay: konteyner to'xtashi bilan avtomatik o'chiriladi, "axlat" qoldirmaydi:
docker run --rm alpine echo "Salom Docker"
# Salom Docker (konteyner echo bajaradi, to'xtaydi va darrov o'chadi)
-it β interaktiv rejim (konteyner ichiga kirish)¶
-it aslida ikki bayroq: -i (interaktiv β kiritishni ochiq tutadi) va -t (TTY β terminal beradi). Birga ular konteyner ichida interaktiv shell ochish imkonini beradi:
Bu yerda alpine image'idan konteyner yaratildi va ichida sh (shell) ishga tushdi β endi konteyner ichida xuddi alohida Linux mashinadagidek buyruqlar terasiz. exit bilan chiqasiz (konteyner ham to'xtaydi).
--restart β qayta ishga tushirish siyosati¶
Server qayta yuklansa yoki konteyner kutilmaganda yiqilsa, uni avtomatik tiklash uchun --restart ishlatiladi:
Variantlari:
| Siyosat | Ma'nosi |
|---|---|
no |
Hech qachon avtomatik qayta ishga tushmaydi (standart) |
on-failure |
Faqat xato bilan (exit code β 0) yiqilsa qayta tushadi |
unless-stopped |
Har doim tiklanadi, lekin siz docker stop qilgan bo'lsangiz β tiklanmaydi |
always |
Har doim tiklanadi (hatto siz to'xtatgan bo'lsangiz ham, daemon qayta ishga tushganda) |
π‘ Production'da xizmat uchun odatda
--restart unless-stoppedtanlanadi β server qayta yuklansa xizmat o'zi ko'tariladi, lekin siz ataylab to'xtatgan bo'lsangiz tinch turadi.
Konteyner hayot sikli¶
Konteyner doim "ishlab turibdi yoki yo'q" emas β uning bir nechta holati bor. Quyidagi diagramma asosiy holatlar va ular orasidagi o'tishlarni ko'rsatadi:
- created β konteyner yaratilgan, lekin hali ishlamayapti (
docker createqilsangiz shu holatga tushadi). - running β ishlab turibdi (
docker runyokidocker start). - paused β vaqtincha "muzlatilgan" (
docker pause),unpausebilan davom etadi β kam ishlatiladi. - stopped / exited β to'xtagan (
docker stop), lekin o'chmagan β ma'lumotlari joyida, qaytastartqilish mumkin. - removed β butunlay o'chirilgan (
docker rm) β ortga qaytmaydi.
π Eng muhim farq: stop β rm.
docker stopkonteynerni to'xtatadi, lekin udocker ps -a'da ko'rinib turadi va unidocker startbilan qayta tiklash mumkin.docker rmesa konteynerni butunlay o'chiradi. Image (asl "suvrat") esa bularning hech birida o'chmaydi β undan yana yangi konteyner yaratish mumkin.
Konteynerlarni boshqarish¶
docker ps β ishlab turgan konteynerlar¶
docker ps (process status) β ishlab turgan konteynerlar ro'yxati:
docker ps
# CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
# b5b28f78d943 nginx "/docker-entrypoint.β¦" Up 2 minutes 0.0.0.0:8080->80/tcp web
To'xtagan konteynerlarni ham ko'rish uchun -a (all) qo'shing:
docker logs β konteyner chiqishini ko'rish¶
Konteyner nima yozayotganini (loglarini) ko'rish β muammo qidirishda eng muhim vosita:
Loglarni jonli kuzatish uchun -f (follow) qo'shing β xuddi tail -f kabi yangi qatorlar ekranga chiqib turadi (Ctrl+C bilan chiqasiz):
Faqat oxirgi qatorlarni ko'rish:
docker exec β ishlab turgan konteyner ichiga kirish¶
docker exec ishlab turgan konteyner ichida buyruq bajaradi. Eng ko'p ishlatiladigani β ichida shell ochish:
-it shu yerda ham kerak (interaktiv terminal). Yoki bitta buyruqni interaktiv kirmasdan bajarish:
π‘ Ba'zi kichik image'larda (
alpineasosidagi)bashyo'q βshishlating. To'liqroq image'lardabashham bor:docker exec -it web bash.
docker stop / start / restart¶
docker stop web # to'xtatadi (10 soniya muloyim kutadi, keyin majburlaydi)
docker start web # to'xtagan konteynerni qayta ishga tushiradi
docker restart web # to'xtatib, qayta ishga tushiradi
docker stop avval konteynerga "to'xta" signalini (SIGTERM) yuboradi va 10 soniya kutadi; xizmat o'zi tugamasa, majburan (SIGKILL) o'chiradi.
docker rm β konteynerni o'chirish¶
docker rm web # FAQAT to'xtagan konteynerni o'chiradi
docker rm -f web # ishlab turgan bo'lsa ham majburan to'xtatib o'chiradi
Bir nechta konteynerni birataga:
To'xtagan barcha konteynerlarni tozalash:
docker inspect β to'liq ma'lumot¶
docker inspect konteyner (yoki image) haqidagi barcha texnik ma'lumotni JSON ko'rinishida beradi β IP manzil, portlar, volume'lar, environment:
Aniq bitta maydonni olish uchun -f (Go shabloni) bilan filtrlang:
docker stats β resurs sarfini kuzatish¶
docker stats konteynerlar qancha CPU/xotira ishlatayotganini jonli ko'rsatadi (Ctrl+C bilan chiqasiz):
docker stats
# NAME CPU % MEM USAGE / LIMIT MEM % NET I/O ...
# web 0.00% 9.5MiB / 7.7GiB 0.12% 1.2kB/0B ...
Bir martalik (jonli emas) suvrat uchun --no-stream:
Image'larni boshqarish¶
Konteynerlar image'lardan tug'iladi, shuning uchun image'larni ham boshqarish kerak.
docker pull β image yuklab olish¶
docker run o'zi ham kerakli image yo'q bo'lsa avtomatik pull qiladi, lekin oldindan yuklab qo'yish (masalan deploy oldidan) foydali.
π Tag'ni doim aniq yozing.
nginxdeb yozsangiz, unginx:latest'ni oladi β bu vaqt o'tib o'zgarib ketishi mumkin. Production'danginx:1.27-alpinekabi aniq versiyani belgilang β qayta-qayta bir xil natija olasiz.
docker images β yuklangan image'lar ro'yxati¶
docker images
# REPOSITORY TAG IMAGE ID SIZE
# nginx 1.27-alpine ... 74.5MB
# redis 7-alpine ... 57.8MB
docker rmi β image o'chirish¶
β οΈ Image'ni shu image'dan yaratilgan konteyner mavjud bo'lsa (hatto to'xtagan bo'lsa ham) o'chira olmaysiz:
image is being used by ... container. Avval konteynerlarni o'chiring.
docker image prune β keraksiz image'lardan tozalash¶
Vaqt o'tib hech qaysi konteyner ishlatmaydigan, "osilib qolgan" (dangling, tagsiz) image'lar yig'iladi β ular disk joyini egallaydi:
docker image prune # faqat dangling (tagsiz) image'larni o'chiradi
docker image prune -a # umuman ishlatilmayotgan barcha image'larni o'chiradi (ehtiyot bo'ling)
Amaliyot: nginx konteynerni boshidan oxirigacha¶
Endi hammasini birlashtiramiz. Quyidagi qadamlar haqiqatan ishga tushirib tekshirilgan (lokal Docker Engine 29.x da, nginx:1.27-alpine image bilan).
1. Ishga tushirish (fonda, 8080-portda, nom bilan):
2. Ishlab turganini tekshirish:
3. Brauzer yoki curl bilan sinash:
Brauzerda http://localhost:8080 ochsangiz ham "Welcome to nginx!" sahifasini ko'rasiz.
4. Loglarni ko'rish:
docker logs web
# /docker-entrypoint.sh: Configuration complete; ready for start up
# ... [notice] 1#1: start worker processes
5. Konteyner ichiga kirish va fayllarni ko'rish:
docker exec web ls /usr/share/nginx/html
# 50x.html
# index.html
docker exec -it web sh
# / # cat /usr/share/nginx/html/index.html | head -3
# / # exit
6. To'xtatish:
7. O'chirish (tozalash):
π‘ Bu β Docker bilan ishlashning kundalik aylanasi: run β ps β logs β exec β stop β rm. Buni bir necha marta takrorlasangiz, qo'lingiz buyruqlarni o'zi yodlab oladi.
Amaliyot: redis konteyner (-e bilan)¶
Endi ma'lumotlar bazasi turidagi xizmatni -e bilan sozlab ishga tushiramiz. Quyidagilar ham haqiqatan tekshirilgan (redis:7-alpine):
# parolli redis ishga tushirish
docker run -d --name cache -e REDIS_ARGS="--requirepass maxfiy" redis:7-alpine
# ichidan parol bilan ulanib tekshirish
docker exec cache redis-cli -a maxfiy PING
# PONG
# resurs sarfini ko'rish
docker stats --no-stream cache
# NAME CPU % MEM USAGE / LIMIT
# cache 0.45% 3.3MiB / 7.7GiB
# tozalash
docker rm -f cache
Bu yerda redis ilovangiz uchun tezkor kesh (cache) sifatida ishlaydi β keyingi boblarda namuna "todo" API'mizni shunga ulaymiz.
βΉοΈ Bu xizmatga host'dan ulanish kerak bo'lsa,
-p 6379:6379qo'shar edingiz. Bu yerda faqat konteyner ichidan sinab ko'rdik, shuning uchun port chiqarish shart bo'lmadi.
Tez-tez uchraydigan xatolar (xulosa)¶
| Xato | Sabab | Yechim |
|---|---|---|
bind: address already in use |
Host porti band (-p 8080:...) |
Boshqa host port tanlang (-p 8081:80) yoki bandlovchini to'xtating |
container name ... already in use |
O'sha --name band |
Eski konteynerni docker rm, yoki boshqa nom |
| Terminal "qotib qoldi" | -d'siz ishga tushirildi |
Ctrl+C, keyin -d bilan qayta |
Cannot connect to the Docker daemon |
Docker ishlamayapti | Docker Desktop/Engine'ni ishga tushiring |
| O'chirgach ma'lumot yo'qoldi | Volume ishlatilmadi | -v nom:/yo'l bilan saqlang (10-bob) |
07-bob mashqlari¶
Mashqlarni o'zingiz terib bajaring. Avval natijani taxmin qiling, keyin buyruqni ishga tushirib solishtiring.
Oson
nginx:1.27-alpineimage'inidocker pullbilan yuklab oling vadocker imagesbilan ro'yxatda borligini tasdiqlang.nginx'ni-d -p 8080:80 --name webbilan ishga tushiring vadocker pschiqishidaSTATUShamdaPORTSustunlarini topib o'qing.- Brauzer yoki
curl http://localhost:8080bilan nginx sahifasini oching. docker logs webbilan loglarni ko'ring, so'ngdocker logs --tail 5 webbilan faqat oxirgi 5 qatorni oling.docker stop webqiling, so'ngdocker psvadocker ps -achiqishidagi farqni tushuntiring.
O'rta
docker exec -it web shbilan konteyner ichiga kiring,/usr/share/nginx/htmlpapkasini ko'ring vaexitbilan chiqing.- To'xtagan
webkonteynernidocker start webbilan qayta ishga tushiring, keyindocker restart webbilan qayta yuklang βdocker ps'daSTATUSo'zgarganini kuzating. docker run --rm alpine echo "salom"ishga tushiring va keyindocker ps -a'da bu konteyner yo'qligini tekshiring. Nega yo'q?
Yechim
--rm bayrog'i konteyner ishini tugatishi (echo bajarilib, to'xtashi) bilan uni avtomatik o'chiradi. Shuning uchun docker ps -a'da ham ko'rinmaydi β bir martalik, vaqtinchalik buyruqlar uchun ideal.
webkonteynerning ichki IP manzilinidocker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' webbilan toping.
Yechim
docker inspect konteyner haqidagi to'liq JSON ma'lumotni beradi; -f (Go shablon) bilan undan faqat kerakli maydonni β bu yerda standart bridge tarmog'idagi IP manzilni β ajratib olamiz. Bu IP konteynerlararo aloqada ishlatiladi (10-bobda batafsil).
- Ataylab xato qiling:
webishlab turgan holda yana bir martadocker run -d -p 8080:80 --name web nginxyozing. Qanday xato chiqdi? Tushuntiring.
Yechim
Ikki xatodan biri (yoki ikkalasi) chiqadi:
yoki port band bo'lsa:
Sabab β --name web allaqachon band va host porti 8080 ham band. Yechim: avval docker rm -f web, yoki boshqa nom (--name web2) va boshqa port (-p 8081:80) tanlash.
Qiyin
- Parol bilan himoyalangan
rediskonteynerni ishga tushiring, ichidanredis-clibilanPINGyuboribPONGjavobini oling, so'ng o'chiring.
Yechim
docker run -d --name cache -e REDIS_ARGS="--requirepass maxfiy" redis:7-alpine
docker exec cache redis-cli -a maxfiy PING
# PONG
docker rm -f cache
-e REDIS_ARGS="--requirepass maxfiy" environment o'zgaruvchisi orqali redis'ga parol o'rnatamiz. docker exec bilan ishlab turgan konteyner ichida redis-cli'ni -a maxfiy (parol) bilan chaqiramiz; PING buyrug'iga PONG qaytsa, xizmat ishlayapti. Oxirida rm -f bilan tozalaymiz.
nginx'ni--restart unless-stoppedbilan ishga tushiring, keyin Docker'ni qayta yuklab (yoki konteynerni majburan yiqitib) uning o'zi tiklanishini kuzating. So'ngdocker stopqilib, endi tiklanmasligini tekshiring.
Yechim
docker run -d -p 8082:80 --name web --restart unless-stopped nginx:1.27-alpine
# yiqilishni taqlid qilamiz (ichidagi asosiy jarayonni o'ldiramiz)
docker exec web sh -c "kill 1"
docker ps # web bir-ikki soniyada yana "Up" bo'lib qaytadi
# endi ataylab to'xtatamiz
docker stop web
docker ps -a # "Exited" - unless-stopped buni TIKLAMAYDI
docker rm -f web
unless-stopped siyosati konteyner yiqilsa yoki daemon qayta ishga tushsa uni avtomatik tiklaydi, lekin siz docker stop bilan ataylab to'xtatgan bo'lsangiz tinch qoldiradi. Bu β production xizmatlar uchun eng ko'p tanlanadigan siyosat.
- Tozalash mashqi:
docker ps -abilan barcha to'xtagan konteynerlarni ko'ring,docker container prunebilan tozalang, so'ngdocker image prunebilan tagsiz image'lardan tozalang. Har qadamdan keyin nima o'zgarganini kuzating.
Yechim
docker ps -a # to'xtagan konteynerlar ro'yxati
docker container prune # tasdiqlang (y) β barcha to'xtaganlar o'chadi
docker image prune # tagsiz (dangling) image'lar o'chadi
docker images # qolgan image'larni tekshiring
prune buyruqlari diskni keraksiz "axlatdan" tozalaydi. container prune faqat to'xtagan konteynerlarni, image prune (bayroqsiz) faqat tagsiz (dangling) image'larni o'chiradi β ishlab turgan konteynerlar va ishlatilayotgan image'larga tegmaydi. Diskni tozalashning eng yengil yo'li. (docker system prune esa hammasini birataga tozalaydi β ehtiyot bo'ling.)
β¬ οΈ Oldingi: 06 β Docker nima: konteynerlar Β· π README Β· Keyingi: 08 β Dockerfile: o'z image'ingiz β‘οΈ