Qatlamlar va kesh — tez build uchun tartib
Muammodan boshlaylik
Dockerfile:
FROM node:22-alpine
WORKDIR /app
COPY . .
RUN npm ci
CMD ["node", "src/index.js"]
src/index.js da bitta vergulni o'zgartirdingiz. docker build — 3 daqiqa: npm ci 800 ta paketni qaytadan yuklayapti. Har bir kichik o'zgarishda. CI serverda har push da.
Xuddi shu natijani 3 soniyada olish mumkin — faqat qatorlar tartibini o'zgartirib.
Har bir instruksiya — qatlam
FROM node:22-alpine # qatlam 1 (asos image qatlamlari)
WORKDIR /app # qatlam 2
COPY package*.json ./ # qatlam 3
RUN npm ci # qatlam 4 — 150 MB
COPY . . # qatlam 5
CMD ["node", "src/index.js"] # metama'lumot (qatlam emas)
RUN, COPY, ADD — har biri yangi qatlam yaratadi. Qatlam — oldingisiga nisbatan fayl tizimidagi o'zgarishlar.
docker history mening-api
IMAGE CREATED BY SIZE
9f2c1a... CMD ["node" "src/index.js"] 0B
<missing> COPY . . 1.2MB
<missing> RUN npm ci 152MB
<missing> COPY package*.json ./ 340kB
<missing> WORKDIR /app 0B
<missing> ... node:22-alpine qatlamlari ...
Kesh qanday ishlaydi
docker build har bir instruksiya uchun so'raydi: "Bu qatlamni oldin yasaganmanmi, va kirishlar o'zgarmaganmi?"
- Ha → keshdan oladi (
CACHED) — bir zumda - Yo'q → qaytadan bajaradi, va undan keyingi barcha qatlamlar ham qaytadan
| Instruksiya | Kesh qachon buziladi |
|---|---|
RUN npm ci |
Buyruq matni o'zgarsa (yoki oldingi qatlam buzilsa) |
COPY src/ ./src/ |
Ko'chirilayotgan fayllardan birortasi o'zgarsa |
FROM |
Asos image yangilangan bo'lsa |
Asosiy qoida: bir qatlam buzilsa — undan keyingilarining hammasi qaytadan quriladi.
Muammoli Dockerfile — nima bo'lyapti
COPY . . # ← index.js o'zgardi → kesh buzildi
RUN npm ci # ← qaytadan! (3 daqiqa) — garchi package.json o'zgarmagan bo'lsa ham
COPY . . barcha fayllarni ko'chiradi, jumladan src/index.js ni. U o'zgardi → qatlam yangi → keyingi npm ci ham qaytadan.
To'g'ri tartib
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json ./ # 1. Faqat bog'liqliklar ro'yxati
RUN npm ci # 2. Bog'liqliklar
COPY . . # 3. Kod — oxirida
CMD ["node", "src/index.js"]
Endi src/index.js o'zgarganda:
=> CACHED [2/5] WORKDIR /app
=> CACHED [3/5] COPY package.json package-lock.json ./
=> CACHED [4/5] RUN npm ci ← keshdan!
=> [5/5] COPY . . ← faqat shu
3 daqiqa → 3 soniya. npm ci faqat package.json / package-lock.json o'zgarganda — ya'ni yangi paket qo'shilganda qayta bajariladi.
Qoida: kam o'zgaradigan narsalar — tepada, ko'p o'zgaradigan narsalar — pastda.
Asos image ← deyarli hech qachon
Tizim paketlari ← kamdan-kam
Bog'liqliklar ← haftada bir
Ilova kodi ← har kuni, har soat
Boshqa tillar — xuddi shu naqsh
# Python
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# PHP
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader
COPY . .
RUN composer dump-autoload --optimize
# Go
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /app/server
RUN larni birlashtirish
# ❌ Uch qatlam; apt keshi image da qoladi
RUN apt-get update
RUN apt-get install -y curl git
RUN rm -rf /var/lib/apt/lists/*
# ✅ Bitta qatlam, kesh tozalangan
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl git \
&& rm -rf /var/lib/apt/lists/*
Nima uchun? Qatlam — o'zgarishlar ro'yxati. Agar fayl bir qatlamda yaratilib, keyingi qatlamda o'chirilsa — u birinchi qatlamda baribir qoladi va image hajmiga kiradi. O'chirish — faqat yaratilgan qatlamning o'zida samarali.
Va yana bir sabab: alohida RUN apt-get update keshlanib qoladi — bir oydan keyin apt-get install eski paket ro'yxati bilan ishlaydi va xato beradi.
BuildKit kesh mount — yanada tez
Paket menejerining o'z keshi (~/.npm, ~/.cache/pip) build lar orasida saqlansin:
# syntax=docker/dockerfile:1
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
package.json o'zgarganda ham npm ci paketlarni internetdan emas, keshdan oladi. Kesh image ga kirmaydi — faqat build mashinasida.
Keshni chetlab o'tish
docker build --no-cache -t ilova . # hammasini noldan
docker build --pull -t ilova . # asos image ning eng yangisini tortib olish
Xavfsizlik yangilanishlari uchun vaqti-vaqti bilan --pull --no-cache — aks holda asos image va tizim paketlari keshlangan eski versiyada qoladi.
Nima uchun shunday?
Nima uchun bitta qatlam o'zgarsa, keyingilarining hammasi qaytadan quriladi — faqat o'zgarganini qayta qurish mumkin emasmi?
Chunki har bir qatlam oldingisi ustiga quriladi va undan bog'liq bo'lishi mumkin. RUN npm ci — COPY package.json natijasiga bog'liq; RUN npm run build — COPY . . ga. Docker buyruq ichida nima bo'layotganini bilmaydi — u RUN ning qaysi fayllarni o'qishini tahlil qila olmaydi. Shuning uchun yagona xavfsiz qoida: oldingi qatlam o'zgardi — keyingilari eskirgan bo'lishi mumkin. Bu qoidani bilsangiz — tartib orqali uni o'zingiz foydangizga ishlatasiz.
Xulosa
Eslab qoling:
RUN,COPY,ADD— har biri qatlam;docker history— ularni ko'rish- Kesh: kirish o'zgarmasa —
CACHED; bitta qatlam buzilsa — keyingilari ham - Kam o'zgaradigan — tepada, ko'p o'zgaradigan — pastda
- Avval
package.json/requirements.txt→ o'rnatish → keyin kod - Bog'liq
RUNlarni&&bilan birlashtiring, kesh/vaqtinchalik fayllarni o'sha qatlamda tozalang RUN --mount=type=cache— paket menejeri keshi--no-cache --pull— vaqti-vaqti bilan xavfsizlik uchun
Keyingi dars
15-dars: .dockerignore — keraksiz fayllarni chiqarib tashlash