Docker

Dockerfile va o'z image'ingizni yaratish

Shu paytgacha biz tayyor image'lardan foydalandik. Endi o'z ilovamiz uchun o'zimizning image'imizni yaratishni o'rganamiz. Buning uchun Dockerfile deb ataladigan maxsus matnli fayl yoziladi. Ushbu dars โ€” Docker'ni real loyihada ishlatishning eng muhim qismi.

Dockerfile nima?

Dockerfile โ€” bu image qanday yaratilishini bosqichma-bosqich tavsiflovchi matnli fayl. Uni retsept deb tasavvur qiling: 'avval bunday asos oling, so'ng bu fayllarni qo'shing, keyin bu buyruqni bajaring...'. Docker shu retseptni o'qib, image yaratadi.

Fayl aynan Dockerfile deb nomlanadi (kengaytmasiz) va loyiha papkasining ildizida joylashadi. Ichida har bir qatorda bitta ko'rsatma (instruction) โ€” katta harflar bilan yozilgan buyruq va uning argumentlari bo'ladi.

FROM โ€” asos image

Har bir Dockerfile FROM ko'rsatmasidan boshlanadi. U qaysi asos image'dan foydalanishni belgilaydi โ€” ya'ni nol nuqta o'rniga tayyor muhitdan boshlaymiz:

FROM node:20

Bu qator: 'Node.js 20 o'rnatilgan tayyor image'ni asos qilib ol' degani. Endi bizda Node.js ishlaydigan muhit bor va uning ustiga o'z kodimizni qo'shamiz. Har doim FROM birinchi ko'rsatma bo'lishi kerak.

Yengilroq image'lar uchun ko'pincha alpine variantini tanlashadi, masalan FROM node:20-alpine. Alpine โ€” juda ixcham Linux distributivi bo'lib, image hajmini bir necha barobar kamaytiradi.

WORKDIR โ€” ish papkasi

WORKDIR konteyner ichidagi ishchi papkani belgilaydi. Undan keyingi barcha buyruqlar shu papkada bajariladi. Agar papka mavjud bo'lmasa, avtomatik yaratiladi:

WORKDIR /app

Endi barcha keyingi COPY, RUN va boshqa ko'rsatmalar /app papkasida ishlaydi. Bu tartibni saqlaydi โ€” kod har doim ma'lum bir joyda bo'ladi.

COPY โ€” fayllarni ko'chirish

COPY ko'rsatmasi fayllarni sizning kompyuteringizdan (host) konteyner ichiga ko'chiradi:

# package.json fayllarini ko'chirish
COPY package.json package-lock.json ./

# Barcha loyiha fayllarini ko'chirish
COPY . .

Sintaksis: COPY manba maqsad. Birinchi argument โ€” kompyuteringizdagi yo'l, ikkinchisi โ€” konteyner ichidagi yo'l (odatda WORKDIR'ga nisbatan). COPY . . degani โ€” joriy papkadagi hamma narsani konteynerning ish papkasiga ko'chir.

RUN โ€” buyruq bajarish (build vaqtida)

RUN image yaratilayotganda (build vaqtida) biror buyruqni bajaradi. Odatda kutubxonalarni o'rnatish uchun ishlatiladi:

RUN npm install

Bu ko'rsatma image quriladigan payt npm installni ishga tushirib, barcha bog'liqliklarni o'rnatadi. Natija image ichida saqlanadi โ€” ya'ni konteyner ishga tushganda kutubxonalar allaqachon o'rnatilgan bo'ladi.

RUN va CMDni chalkashtirmang! RUN โ€” image yaratilayotganda (bir marta) bajariladi. CMD โ€” konteyner ishga tushganda bajariladi. RUN npm install โ€” o'rnatish, CMD npm start โ€” ilovani ishga tushirish.

ENV โ€” muhit o'zgaruvchilari

ENV image ichida muhit o'zgaruvchilarini o'rnatadi:

ENV NODE_ENV=production
ENV PORT=3000

Bu o'zgaruvchilar konteyner ichidagi ilova uchun mavjud bo'ladi. Node.js'da ularni process.env.NODE_ENV orqali o'qishingiz mumkin. Bu sozlamalarni koddan ajratib olishning qulay usuli.

EXPOSE โ€” portni e'lon qilish

EXPOSE konteyner qaysi portda ishlashini hujjatlashtiradi:

EXPOSE 3000
Muhim nozik nuqta: EXPOSE o'zi portni ochmaydi! U shunchaki hujjat sifatida 'bu ilova 3000-portda ishlaydi' deb belgilaydi. Portni haqiqatan ochish uchun konteynerni ishga tushirganda -p 3000:3000 bayrog'ini berishingiz kerak.

CMD โ€” konteyner ishga tushganda bajariladigan buyruq

CMD โ€” konteyner ishga tushganda bajariladigan asosiy buyruq. Odatda ilovani ishga tushirish buyrug'i:

CMD ["npm", "start"]

Bu ko'rsatma konteyner har safar ishga tushganda npm startni bajaradi. Dockerfile'da odatda faqat bitta CMD bo'ladi โ€” u konteynerning asosiy vazifasini belgilaydi.

To'liq Dockerfile namunasi (Node.js ilova)

Endi barcha ko'rsatmalarni birlashtirib, oddiy Node.js ilova uchun to'liq Dockerfile yozamiz:

# 1. Asos image โ€” Node.js 20
FROM node:20-alpine

# 2. Ish papkasini belgilash
WORKDIR /app

# 3. Avval faqat package fayllarini ko'chirish (kesh uchun)
COPY package.json package-lock.json ./

# 4. Kutubxonalarni o'rnatish
RUN npm install

# 5. Qolgan barcha kodni ko'chirish
COPY . .

# 6. Muhit o'zgaruvchisi
ENV NODE_ENV=production

# 7. Ilova ishlaydigan port
EXPOSE 3000

# 8. Konteyner ishga tushganda ishlaydigan buyruq
CMD ["npm", "start"]
Diqqat qiling: biz avval faqat package.jsonni ko'chirib, npm installni bajaramiz, keyin qolgan kodni ko'chiramiz. Bu keshdan foydalanish uchun ataylab qilingan โ€” buni quyida tushuntiramiz.

docker build โ€” image yaratish

Dockerfile tayyor bo'lgach, undan image yaratish uchun docker build ishlatiladi:

docker build -t mening-ilovam:1.0 .

Yaratilgach, image'ni ishga tushirasiz:

docker run -d -p 3000:3000 --name ilova mening-ilovam:1.0

Qatlamlar (layers) va kesh

Docker image qatlamlardan (layers) tashkil topadi. Dockerfile'dagi har bir ko'rsatma (FROM, COPY, RUN...) alohida qatlam yaratadi. Docker bu qatlamlarni keshlaydi โ€” ya'ni saqlab qoladi.

Qayta build qilganda, agar biror ko'rsatma va undan oldingi hamma narsa o'zgarmagan bo'lsa, Docker uni qayta bajarmaydi โ€” keshdagi tayyor qatlamdan foydalanadi. Bu build'ni ancha tezlashtiradi.

Aynan shu sababli biz package.jsonni alohida ko'chirdik: agar faqat kodni o'zgartirsangiz (lekin kutubxonalar o'zgarmasa), Docker npm install qatlamini keshdan oladi va uni qaytadan bajarmaydi. Bu vaqtni sezilarli tejaydi.

Kesh qoidasi: Docker Dockerfile'ni yuqoridan pastga bajaradi. Biror qatlam o'zgarsa, undan keyingi barcha qatlamlar qayta bajariladi. Shuning uchun kam o'zgaradigan narsalarni (bog'liqliklar) yuqoriga, tez-tez o'zgaradiganlarni (kod) pastga qo'yish maqsadga muvofiq.

.dockerignore fayli

COPY . . hamma narsani ko'chiradi โ€” shu jumladan keraksiz fayllarni ham (masalan, node_modules, git fayllari). Ularni chetlab o'tish uchun loyiha ildizida .dockerignore fayli yaratiladi:

node_modules
npm-debug.log
.git
.gitignore
.env
Dockerfile
*.md

Bu .gitignorega o'xshaydi: bu yerda ko'rsatilgan fayllar COPY vaqtida e'tiborga olinmaydi. Bu image hajmini kamaytiradi va build'ni tezlashtiradi. node_modulesni chetlab o'tish ayniqsa muhim โ€” chunki u konteyner ichida npm install orqali qayta o'rnatiladi.

Xulosa