08 β Dockerfile: o'z image'ingiz¶
β¬ οΈ Oldingi: 07 β Konteyner bilan ishlash Β· π README Β· Keyingi: 09 β Image optimizatsiya va registry β‘οΈ
Bu bobda: tayyor image yetmaganda o'z ilovangizni Dockerfile orqali image'ga paketlashni o'rganamiz β
FROM/WORKDIR/COPY(va negaADDemas)/RUN/ENV/ARG/EXPOSE/LABEL/USERdirektivalari, har direktiva bir layer ekani va layerlar qanday keshlanishi,CMDvaENTRYPOINTfarqi (shell vs exec form), eng muhim optimizatsiya βCOPY package.json+RUN npm installniCOPY . .dan oldin qo'yib build keshini saqlash,.dockerignore, vadocker build -t myapp:1.0 .bilan namuna Express "vazifalar" ilovasini real image'ga aylantirib, ishga tushirib ko'rsatamiz.
Muammo: tayyor image yetmaydi¶
Oldingi bobda biz docker run nginx yoki docker run node kabi tayyor image'larni ishga tushirdik. Ular zo'r β lekin ularning ichida sizning ilovangiz yo'q. node image'i faqat Node.js bor toza muhit; sizning server.js faylingizni, package.json'ingizni va bog'liqliklaringizni hech kim u yerga qo'ymagan.
Ikkita yomon yo'l bor:
- Har safar qo'lda. Konteynerni ishga tushirib, ichiga
docker cpbilan kodni ko'chirish,npm installqilish, keyin ishga tushirish. Konteyner o'chsa β hammasi yo'qoladi. Bu 05-bobdagi "qo'lda deploy" og'rig'ining aynan o'zi, faqat konteyner ichida. - Volume bilan ulash. Kodingizni tashqaridan mount qilish β lekin u holda image ko'chirib bo'lmaydigan bo'lib qoladi: boshqa serverga olib borsangiz, kod va bog'liqliklar yana qo'lda kerak.
Bizga kerak narsa: kod + bog'liqlik + ishga tushirish buyrug'i hammasi bitta image ichida, qotirilgan holda. Bir marta quramiz β istalgan joyda bir xil ishlaydi. Buni qiladigan retsept fayli β Dockerfile.
π Image β ilovangizning "muzlatilgan surati": OS qatlami + Node + sizning kodingiz + bog'liqliklar, bari ichida. Dockerfile β shu surat qanday quriladi, qadam-baqadam yozilgan retsept.
docker buildretseptni o'qib image yasaydi;docker runesa image'dan konteyner ishga tushiradi.
Bu bobda biz kitob bo'ylab ishlatadigan namuna ilovani β kichik "vazifalar" API'sini (Node.js + Express) β to'liq image'ga aylantiramiz.
Birinchi Dockerfile¶
Dockerfile β bu oddiy matn fayl, odatda ilova ildizida joylashadi va aynan Dockerfile deb nomlanadi (kengaytmasiz). Har qatori bitta direktiva: katta harf bilan yoziladigan buyruq (FROM, COPY, RUN, ...) va uning argumenti.
Mana namuna "vazifalar" ilovamiz uchun to'liq, ishlaydigan Dockerfile (har qatorni quyida tushuntiramiz):
# 1) Base image: kichik, rasmiy Node.js LTS (Alpine Linux)
FROM node:lts-alpine
# Image metadatasi (MAINTAINER emas, LABEL)
LABEL org.opencontainers.image.title="Vazifalar API" \
org.opencontainers.image.description="Oddiy Express ilovasi"
# 2) Ish papkasi konteyner ichida
WORKDIR /app
# 3) AVVAL faqat bog'liqlik manifestini ko'chiramiz (kesh uchun)
COPY package*.json ./
# 4) Bog'liqliklarni aniq, qayta-takrorlanadigan tarzda o'rnatamiz
RUN npm ci --omit=dev
# 5) Endi qolgan kodni ko'chiramiz
COPY . .
# 6) Ilova qaysi portni tinglashini hujjatlashtiramiz
EXPOSE 3000
# 7) root emas, oddiy foydalanuvchi (xavfsizlik)
USER node
# 8) Konteyner ishga tushganda nima bajariladi (exec-form)
CMD ["node", "server.js"]
Bir necha qatorda butun ilova paketlandi. Endi har bir direktivani tartib bilan ochamiz.
Direktivalar: retsept tili¶
FROM β poydevor¶
Har Dockerfile FROM bilan boshlanadi: qaysi tayyor image ustiga quramiz. Bu base image (poydevor image). Biz noldan OS yozmaymiz β Node.js o'rnatilgan tayyor node:lts-alpine'dan boshlaymiz. lts β Node'ning uzoq qo'llab-quvvatlanadigan versiyasi, alpine β juda kichik Linux (image hajmi keskin kichik bo'ladi; 09-bobda batafsil).
π‘ Doim aniq tag ishlating (
node:lts-alpine,node:22-alpine),node:latestemas.latestertaga boshqa versiyaga aylanib, kutilmagan buzilishga olib kelishi mumkin.
WORKDIR β ish papkasi¶
Konteyner ichidagi joriy papkani belgilaydi. Bundan keyingi COPY, RUN, CMD shu papkadan ishlaydi. Papka bo'lmasa β yaratiladi. Bu RUN mkdir /app && cd /app'dan toza va to'g'ri yo'l.
COPY β fayllarni ichkariga ko'chirish (va nega ADD emas)¶
COPY <manba> <manzil> β build kontekstidagi (sizning loyiha papkangizdagi) fayllarni image ichiga ko'chiradi. COPY . . β joriy papkadagi hammasini WORKDIR'ga.
ADD ham bor va o'xshash, lekin uning ikkita "sehrli" qo'shimcha xatti-harakati bor: u URL'dan yuklab olishi va .tar arxivni avtomatik ochishi mumkin. Aynan shu "sehr" tushunarsiz xatolarga sabab bo'ladi.
π
COPY'ni afzal ko'ring,ADD'dan qoching.COPYaynan ko'chiradi, boshqa hech narsa qilmaydi β bashorat qilinadigan.ADD'ni faqat haqiqatan lokal.tarni ochish kerak bo'lganda ishlating. Buni Docker rasmiy qo'llanmasi ham tavsiya qiladi.
RUN β image qurilayotganda buyruq bajarish¶
RUN β image qurilish vaqtida (build) buyruq bajaradi va natijani image'ga qotiradi. Bu yerda biz bog'liqliklarni o'rnatamiz. Biz npm install emas, npm ci ishlatdik: u package-lock.json'ga aniq mos keladigan versiyalarni o'rnatadi β qayta-takrorlanadigan (reproducible) va tezroq. --omit=dev esa faqat production bog'liqliklarini o'rnatadi (test/lint paketlari image'ga tushmaydi).
β οΈ
RUNbilanCMD/ENTRYPOINTni adashtirmang.RUNβ build paytida (image yasalayotganda),CMD/ENTRYPOINTβ konteyner ishga tushganda.RUN npm ciimage ichiga bog'liqliklarni o'rnatadi;CMD ["node","server.js"]esa keyin har run'da ilovani ishga tushiradi.
ENV va ARG β o'zgaruvchilar¶
ENVβ konteyner ichida ishlash vaqtida mavjud bo'ladigan muhit o'zgaruvchisi. Ilovaprocess.env.PORTorqali o'qiy oladi.ARGβ faqat build vaqtida mavjud bo'ladigan o'zgaruvchi;docker build --build-arg NODE_ENV=production .bilan beriladi. Konteyner ichidaARGko'rinmaydi.
Soddasi: ARG = qurilish parametri, ENV = ishlash vaqtidagi sozlama.
EXPOSE β qaysi portni tinglaydi¶
Bu β hujjatlashtiruvchi direktiva: "bu ilova 3000-portni tinglaydi" deb belgilaydi. U portni o'zi ochmaydi β portni tashqariga ulash uchun baribir docker run -p 8090:3000 kerak (07-bobdan). EXPOSE boshqa odamga (va Docker vositalariga) qaysi port muhimligini ko'rsatadi.
LABEL β metadata (MAINTAINER emas)¶
LABEL org.opencontainers.image.title="Vazifalar API" \
org.opencontainers.image.source="https://github.com/foydalanuvchi/vazifalar"
LABEL β image'ga "kim, nima, qaysi versiya" kabi metadata yopishtiradi (docker inspect bilan ko'rinadi).
β οΈ
MAINTAINEReskirgan (deprecated). Eski qo'llanmalardaMAINTAINER Ism <email>ko'rasiz β endi ishlatmang. O'rniga:LABEL org.opencontainers.image.authors="Ism <email>".
USER β root'dan voz keching¶
Standart holatda konteyner ichidagi jarayon root (super-foydalanuvchi) sifatida ishlaydi β agar ilovada zaiflik bo'lsa, hujumchi konteynerda root huquqiga ega bo'ladi. USER node β node image'ida oldindan tayyor turgan oddiy node foydalanuvchisiga o'tadi.
π Eng yaxshi amaliyot: konteynerni non-root foydalanuvchi sifatida ishlating.
USER'niCOPY/RUN'dan keyin qo'ying (avval fayllarni root sifatida joylab, keyin huquqni pasaytirasiz).
CMD va ENTRYPOINT β nima ishga tushadi¶
Bu eng ko'p chalkashtiriladigan ikki direktiva. Ikkalasi ham konteyner ishga tushganda nima bajarilishini belgilaydi, lekin xulqi farq qiladi.
CMD β standart buyruq, lekin almashtirilishi mumkin. docker run myapp echo salom desangiz, node server.js o'rniga echo salom ishlaydi.
ENTRYPOINT β konteynerning "asosiy dasturi"; docker run'da bergan argumentlar uni almashtirmaydi, balki unga qo'shiladi.
Ikkalasini birga ishlatish β eng kuchli idiom. ENTRYPOINT = qat'iy dastur, CMD = unga standart argument:
docker run myappβnode server.js --port 3000docker run myapp --port 8080βnode server.js --port 8080(CMDalmashdi,ENTRYPOINTqoldi)
Bizning oddiy ilovamiz uchun yolg'iz CMD yetarli β moslashuvchanroq, chunki kerak bo'lsa docker run myapp sh bilan ichkariga kirib ko'rish oson.
Exec-form vs shell-form¶
Bu ikki yozuv juda muhim farqqa ega:
# exec-form (TAVSIYA ETILADI) β JSON massiv, qo'shtirnoq bilan
CMD ["node", "server.js"]
# shell-form β oddiy matn
CMD node server.js
- Exec-form (
["node", "server.js"]) β buyruqni to'g'ridan-to'g'ri bajaradi (PID 1 sifatida). Konteynerni to'xtatish signali (SIGTERM,docker stop) ilovaga to'g'ri yetadi β toza o'chish. - Shell-form (
node server.js) β/bin/sh -c "node server.js"orqali ishlaydi; signalsh'da qoladi, ilovaga yetmasligi mumkin β konteyner sekin, "majburan" o'chadi.
π Doim exec-form ishlating (
CMD ["...", "..."]JSON massiv). Bu signal boshqaruvini to'g'rilaydi vadocker stopilovani toza yopadi.
Quyidagi diagramma CMD va ENTRYPOINT farqini umumlashtiradi:
Layerlar: image β qatlamlar steki¶
Bu bobning yuragi shu yerda. Dockerfile'dagi har bir direktiva (FROM, COPY, RUN, ...) image'ga bitta yangi layer (qatlam) qo'shadi. Image β bu layerlarning ustma-ust qo'yilgan steki (uyumi). Har layer faqat o'zidan oldingi holatga nisbatan o'zgarishni saqlaydi.
Buni varaqlar uyumiga o'xshating: FROM β eng pastdagi varaq (Node bor OS), keyin har direktiva ustiga yangi shaffof varaq qo'yadi (WORKDIR papka yasadi, COPY package*.json manifest qo'shdi, RUN npm ci node_modules yasadi...). Image β shu varaqlar yig'indisi.
Eng muhim xususiyat: layerlar keshlanadi va qayta ishlatiladi. docker buildni ikkinchi marta ishga tushirganda, Docker har layer uchun "kirish ma'lumotlari o'zgarmadimi?" deb tekshiradi. O'zgarmagan bo'lsa β qaytadan qurmaydi, keshdan oladi (CACHED deb ko'rsatadi). Kesh birinchi o'zgargan layergacha ishlaydi: o'sha layer (va undan keyingi hammasi) qaytadan quriladi.
βΉοΈ Ikki tushuncha aralashmasin: layer β image quruvchi bloki (qurilish vaqtida hosil bo'ladi va keshlanadi); 07-bobdagi konteyner qatlami esa image'ning yuqorisidagi yozish mumkin bo'lgan vaqtinchalik qatlam (run vaqtida). Image layerlari o'qish-uchun (read-only) va konteynerlar o'rtasida umumiy.
Build kesh va tartib β eng muhim optimizatsiya¶
Layer keshini bilsangiz, undan foyda olishingiz kerak. Sir tartibda: kam o'zgaradigan narsalarni yuqoriga, tez-tez o'zgaradigan narsalarni pastga qo'ying.
Ilovangizda nima tez-tez o'zgaradi? Kod (server.js). Nima kamdan-kam o'zgaradi? Bog'liqliklar (package.json β yangi paket qo'shganingizdagina o'zgaradi). Shuning uchun:
COPY package*.json ./ # avval faqat manifest
RUN npm ci --omit=dev # bog'liqliklarni o'rnat
COPY . . # keyin qolgan kod
Endi kodingizni o'zgartirsangiz (server.js'ni tahrirlasangiz), package*.json o'zgarmagani uchun COPY package*.json va og'ir RUN npm ci layerlari keshdan olinadi β bog'liqliklar qayta o'rnatilmaydi. Faqat COPY . . qaytadan ishlaydi (bir lahzada).
β Noto'g'ri tartib (har kod o'zgarishida bog'liqliklarni qayta o'rnatadi):
Bunda COPY . . kodingiz har o'zgarganda layer keshini buzadi β undan keyingi RUN npm ci ham keshdan tushadi va har safar noldan ishlaydi (sekin: o'nlab soniya, ba'zan daqiqalar).
Quyidagi diagramma ikkala tartibni yonma-yon ko'rsatadi β kod o'zgarganda:
π‘ Bu β Dockerfile'dagi eng muhim optimizatsiya saboq. Faqat ikki qatorni to'g'ri tartiblash bilan build vaqtini daqiqalardan soniyalarga tushirasiz. Xuddi shu naqsh barcha tillarda ishlaydi: Python'da
COPY requirements.txtβRUN pip installβCOPY . .; Go'daCOPY go.mod go.sumβRUN go mod downloadβCOPY . ..
Biz buni haqiqatan tekshirdik: to'g'ri tartibli image'ni qurib, keyin faqat server.js'ni o'zgartirib qayta qurganimizda Docker WORKDIR, COPY package*.json va RUN npm ci layerlarini CACHED deb belgiladi β faqat COPY . . qayta ishladi. Noto'g'ri tartibda esa har kod o'zgarishida npm ci qaytadan ishladi.
.dockerignore β kontekstga nima tushmasin¶
docker build -t myapp:1.0 . desangiz, oxiridagi nuqta (.) β bu build konteksti: Docker shu papkadagi hamma faylni daemonga jo'natadi. Agar papkangizda node_modules (yuzlab megabayt), .git tarixi yoki .env (sirlaringiz) bo'lsa β ular ham jo'natiladi. Bu sekin, og'ir va xavfli.
Yechim β .dockerignore fayli (xuddi .gitignore kabi):
node_modulesβ image ichidaRUN npm cibilan toza o'rnatamiz; lokal (ehtimol boshqa OS uchun qurilgan)node_modules'ni ko'chirish noto'g'ri vaCOPY . .keshini ham buzadi..gitβ butun versiya tarixi image'ga kerak emas, faqat hajmni shishiradi..envβ sirlar (parol, API kalit) image ichiga hech qachon tushmasin. Ularni run vaqtida-eyoki Compose/secrets bilan beriladi.
β οΈ
.env'ni image'gaCOPYqilmang. Image ko'pincha registry'ga (boshqalar ko'radigan joyga) jo'natiladi β ichidagi parol ochiq qoladi..dockerignore'ga.env'ni qo'shish β birinchi himoya.
Image'ni qurish va ishga tushirish¶
Endi hammasini birga ko'ramiz. Loyiha papkasida Dockerfile, .dockerignore, package.json, package-lock.json va server.js bor.
1) Image'ni quramiz:
-t vazifalar:1.0β image'ga tag (nom:versiya) beradi.- oxiridagi
.β build konteksti (joriy papka). Docker shu papkadanDockerfileni topib o'qiydi.
Kutilgan chiqish (qisqartirilgan):
=> [1/5] FROM docker.io/library/node:lts-alpine
=> [2/5] WORKDIR /app
=> [3/5] COPY package*.json ./
=> [4/5] RUN npm ci --omit=dev
=> [5/5] COPY . .
=> exporting to image
=> naming to docker.io/library/vazifalar:1.0
2) Image ro'yxatda turibdimi β tekshiramiz:
3) Konteyner sifatida ishga tushiramiz:
-dβ fonda (detached),--nameβ qulay nom,-p 8090:3000β host'ning 8090-portini konteynerning 3000-portiga ulaydi (07-bobdan).
4) Ishlayotganini tekshiramiz:
Ishladi β bizning kod o'z image'imiz ichida konteyner bo'lib aylanmoqda. Yangi vazifa qo'shib ko'ramiz:
curl -X POST http://localhost:8090/vazifalar \
-H "Content-Type: application/json" \
-d '{"matn":"Image push qilish"}'
5) Konteyner haqiqatan non-root ekanini tekshiramiz (USER node ishladimi):
Root emas, node β to'g'ri.
6) Tozalash:
β Tekshirildi. Bu bobdagi
Dockerfile, namuna Express ilova va build kesh saboq lokal Docker'da (Engine 29.x) haqiqatan ishga tushirildi:docker buildmuvaffaqiyatli yakunlandi, konteynernodefoydalanuvchi sifatida ishladi,curlGET va POST so'rovlariga to'g'ri javob berdi, build keshi to'g'ri tartibdanpm ciniCACHEDqildi, noto'g'ri tartibda esa qayta qurdi. So'ng image va konteyner tozalandi.
Tez ma'lumotnoma¶
| Direktiva | Vazifasi | Misol |
|---|---|---|
FROM |
Base image | FROM node:lts-alpine |
WORKDIR |
Ish papkasi | WORKDIR /app |
COPY |
Fayl ko'chirish (afzal) | COPY . . |
ADD |
COPY + URL/tar (kamdan-kam) | ADD x.tar.gz /app |
RUN |
Build paytida buyruq | RUN npm ci --omit=dev |
ENV |
Run paytidagi o'zgaruvchi | ENV PORT=3000 |
ARG |
Build paytidagi o'zgaruvchi | ARG NODE_ENV |
EXPOSE |
Tinglanadigan port (hujjat) | EXPOSE 3000 |
LABEL |
Metadata (MAINTAINER emas) |
LABEL ...title="API" |
USER |
Non-root foydalanuvchi | USER node |
CMD |
Standart buyruq (almashadi) | CMD ["node","server.js"] |
ENTRYPOINT |
Asosiy dastur (qo'shiladi) | ENTRYPOINT ["node","server.js"] |
08-bob mashqlari¶
Ko'pchilik mashq lokal Docker o'rnatilgan kompyuterda bajariladi. Har mashqdan keyin yaratgan konteyner/image'laringizni
docker rm -fvadocker rmibilan tozalab boring.
Oson¶
-
Bo'sh papkada bitta
index.js(console.log("Salom Docker")) yarating va shuni ishga tushiradigan eng kichikDockerfileyozing (FROM node:lts-alpine,WORKDIR,COPY,CMD).docker build -t salom:1.0 .qiling. -
docker imagesbilan yaratgan image'ingizni toping. UningSIZEustunini yozib oling. -
salom:1.0image'inidocker run salom:1.0bilan ishga tushiring vaSalom Dockerchiqishini ko'ring. -
Dockerfile'daMAINTAINERqatorini ko'rdingiz deylik. Uni qaysi direktivaga almashtirasiz? Bitta qatorda yozing.
O'rta¶
- Yuqoridagi "vazifalar"
Dockerfile'idaCMD ["node", "server.js"]ni shell-formga (CMD node server.js) o'zgartiring. Build qilib, konteynernidocker stopbilan to'xtating β qaysi formdocker stop'da tezroq to'xtaydi? Nega?
Yechim
Exec-form (CMD ["node", "server.js"]) tezroq va toza to'xtaydi. Shell-form'da buyruq /bin/sh -c "node server.js" orqali ishlaydi: docker stop jo'natgan SIGTERM signali sh jarayoniga boradi, lekin Node'ga uzatilmasligi mumkin. Shuning uchun konteyner SIGTERM'ga javob bermay, ~10 soniyadan keyin SIGKILL bilan majburan o'chadi. Exec-form'da Node to'g'ridan-to'g'ri PID 1 bo'ladi, signalni o'zi oladi va darrov toza yopiladi. Doim exec-form (JSON massiv) ishlating.
EXPOSE 3000bo'lgan image'nidocker runbilan-psiz ishga tushiring. Brauzerdan/curl'dan unga ulanib ko'ring. Nima bo'ladi va nega?
Yechim
Ulanib bo'lmaydi. EXPOSE faqat hujjatlashtiruvchi direktiva β u portni tashqariga ochmaydi. Portni host'ga ulash uchun baribir docker run -p 8090:3000 ... kerak. EXPOSE shunchaki "bu ilova 3000-portni tinglaydi" deb belgilaydi, boshqa hech narsa qilmaydi.
-
.dockerignorefaylini namuna ilovaga qo'shing (node_modules,.git,.env). Build qiling. Keyin.dockerignore'ni o'chirib qayta build qiling β build kontekstining hajmi (transferring context) qanchaga oshdi? -
ENV PORT=4000niDockerfile'ga qo'shing va ilovaniprocess.env.PORT'ni o'qiydigan qiling. Build qilib,-p 8090:4000bilan ishga tushiring. Endi konteyner qaysi portni tinglaydi?
Yechim
Dockerfile'ga ENV PORT=4000 qo'shilgach, ilova (process.env.PORT || 3000 mantig'i bilan) 4000-portni tinglaydi. Shuning uchun EXPOSE'ni ham EXPOSE 4000ga o'zgartirib, docker run -p 8090:4000 vazifalar:1.0 bilan ishga tushirasiz β host'ning 8090-porti konteynerning 4000-portiga ulanadi. ENV β run vaqtidagi sozlama bo'lgani uchun ilova uni process.env orqali ko'radi.
Qiyin¶
- Namuna "vazifalar" ilovasiga to'liq
Dockerfileyozing:FROM node:lts-alpine,WORKDIR /app,COPY package*.json ./,RUN npm ci --omit=dev,COPY . .,EXPOSE 3000,USER node,CMD ["node","server.js"]. Build qiling,-p 8090:3000bilan ishga tushiring,curl http://localhost:8090/vazifalarbilan tasdiqlang.
Yechim
Dockerfile:
FROM node:lts-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
USER node
CMD ["node", "server.js"]
Build va run:
docker build -t vazifalar:1.0 .
docker run -d --name vazifalar-c -p 8090:3000 vazifalar:1.0
curl http://localhost:8090/vazifalar
# [{"id":1,"matn":"Dockerfile yozish","bajarildi":false}]
docker rm -f vazifalar-c && docker rmi vazifalar:1.0
COPY package*.json ./ + RUN npm cini COPY . .dan oldin qo'ygani uchun keyinchalik kod o'zgarsa ham bog'liqlik keshi saqlanadi.
- Build kesh isboti. 9-mashqdagi image'ni quring. Endi faqat
server.js'ni o'zgartiring (bitta izoh qo'shing) vadocker buildni qayta ishga tushiring. Chiqishda qaysi qadamlarCACHEDdeb belgilanadi? Endipackage.json'ga yangi paket qo'shib qayta quring β endi nima o'zgaradi?
Yechim
Faqat server.js o'zgarganda WORKDIR, COPY package*.json ./ va og'ir RUN npm ci qadamlari CACHED bo'ladi β faqat COPY . . (va undan keyingilar) qaytadan ishlaydi:
=> CACHED [2/5] WORKDIR /app
=> CACHED [3/5] COPY package*.json ./
=> CACHED [4/5] RUN npm ci --omit=dev
=> [5/5] COPY . .
package.json o'zgarganda esa COPY package*.json ./ keshi buziladi β undan keyingi RUN npm ci ham qaytadan ishlaydi (bog'liqliklar yangidan o'rnatiladi). Saboq: kam o'zgaradigan bog'liqliklarni yuqoriga, tez o'zgaradigan kodni pastga qo'ying.
- Noto'g'ri tartib bilan taqqoslang.
COPY . .niRUN npm cidan oldin qo'yilgan ikkinchiDockerfileyozing. Birini, keyin ikkinchisini quring; keyin ikkalasida ham faqat kodni o'zgartirib qayta quring. Qaysi biri har safarnpm cini qayta ishlatadi? Vaqtni o'lchang.
Yechim
Noto'g'ri tartibli Dockerfile:
Bunda kod har o'zgarganda COPY . . keshi buziladi (kod kontekstning bir qismi), shuning uchun undan keyingi RUN npm ci har safar qaytadan ishlaydi β sekin. To'g'ri tartibda esa npm ci CACHED qoladi. time docker build ... bilan o'lchasangiz, to'g'ri tartib soniyalar, noto'g'ri tartib o'nlab soniyada tugaydi.
CMDvaENTRYPOINTni birga ishlatadiganDockerfileyozing:ENTRYPOINT ["node", "server.js"]vaCMD ["--port", "3000"].docker run myappvadocker run myapp --port 8080ikki holatda konteyner ichida qanday to'liq buyruq ishga tushadi?
Yechim
docker run myappβnode server.js --port 3000(CMDstandart argument sifatida ishlatildi).docker run myapp --port 8080βnode server.js --port 8080(run'dagi argumentCMDni almashtirdi,ENTRYPOINTo'zgarmadi).
ENTRYPOINT β qat'iy "asosiy dastur", CMD β almashtiriladigan standart argument. Bu naqsh ilovani har doim node server.js orqali ishga tushishini kafolatlaydi, lekin argumentni moslashuvchan qoldiradi.
docker buildchiqishidagiSending build context/transferring contextqatorini toping. Loyihangizga 200MB lik fayl qo'shsangiz (.dockerignore'ga kiritmasdan), bu raqam qanday o'zgaradi? Nega.dockerignoremuhim?
Yechim
Build konteksti β docker build .dagi . papkadagi hamma fayl (.dockerignore'da istisno qilinmaganlari). 200MB lik fayl qo'shilsa, u ham daemonga jo'natiladi β kontekst hajmi ~200MB ga oshadi, build sekinlashadi va u fayl kerak bo'lmasa ham. .dockerignore bilan keraksiz narsalarni (node_modules, .git, katta fayllar) chiqarib tashlash kontekstni kichik, build'ni tez va image'ni xavfsiz (.env tushmaydi) qiladi.
β¬ οΈ Oldingi: 07 β Konteyner bilan ishlash Β· π README Β· Keyingi: 09 β Image optimizatsiya va registry β‘οΈ