5-bo‘lim

Qatlam keshi va qurish tartibi

Kesh qanday ishlaydi, nima uni buzadi va Dockerfile ko'rsatmalarini qanday tartibda yozish kerak.

🕑 12 daqiqa o‘qish 📄 818 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Kesh qanday ishlaydi
  2. Ikki Dockerfile
  3. O'lchab ko'ramiz
  4. Keshni nima buzadi?
  5. Bir RUN ichida tozalash
  6. Keshni ataylab chetlab o'tish
  7. Kesh ham joy egallaydi
  8. Xulosa

Birinchi qurish sekin bo'lishi tabiiy. Lekin har bir qurish sekin bo'lsa - Dockerfile noto'g'ri yozilgan.

Bu bob bitta amaliy qoida haqida: kam o'zgaradigan narsa yuqorida, tez-tez o'zgaradigan narsa pastda.

Kesh qanday ishlaydi #

Docker har bir ko'rsatma uchun kesh kaliti hisoblaydi. Kalit ikki narsadan tuziladi:

Ko'rsatma turiKalitga nima kiradi
RUN, ENV, CMDKo'rsatma matni
COPY, ADDKo'rsatma matni va ko'chiriladigan fayllar mazmuni

Kalit oldingi qurishdagi bilan bir xil bo'lsa - qadam bajarilmaydi, tayyor qatlam olinadi.

Eng muhim qoida esa bu:

Bitta qadam buzilsa - undan keyingi hammasi buziladi To'g'ri tartib FROM alpine kesh COPY bogliqliklar.txt kesh RUN apk add curl kesh COPY ilova.sh qayta 3 ta qadam keshdan Noto'g'ri tartib FROM alpine kesh COPY . . qayta RUN apk add curl qayta CMD qayta 1 ta qadam keshdan Kesh faqat pastga qarab buziladi Bitta qadamning kaliti o'zgarsa, undan keyingi barcha qadamlar qaytadan bajariladi - chunki ularning asosi endi boshqa.
Kod har kuni o'zgaradi, bog'liqliklar esa oyda bir marta

Ikki Dockerfile #

Bir xil ishni bajaradigan ikkita variantni solishtiramiz.

To'g'ri tartib - bog'liqliklar avval, kod keyin:

DOCKERFILE
FROM alpine:3.21
WORKDIR /ilova
COPY bogliqliklar.txt .
RUN apk add --no-cache curl
COPY ilova.sh .
CMD ["sh", "ilova.sh"]

Noto'g'ri tartib - hammasi birdan:

DOCKERFILE
FROM alpine:3.21
WORKDIR /ilova
COPY . .
RUN apk add --no-cache curl
CMD ["sh", "ilova.sh"]

Farq bitta qatorda: COPY . . hamma narsani ko'chiradi, shu jumladan tez-tez o'zgaradigan kodni. Demak har kod o'zgarganda uning kesh kaliti o'zgaradi - va undan keyingi RUN apk add ham qaytadan bajariladi.

O'lchab ko'ramiz #

Ikkala obraz ham bir marta qurilgan, kesh to'la. Endi kodni o'zgartirib, qaytadan quramiz va nechta qadam keshdan olinganini sanaymiz:

Terminal
echo 'echo "dokon r1"' > ilova.sh
docker build -f Dockerfile.yaxshi -t yaxshi:2 . 2>&1 | grep -c CACHED
Natija
3
Terminal
echo 'echo "dokon z1"' > ilova.sh
docker build -f Dockerfile.yomon -t yomon:2 . 2>&1 | grep -c CACHED
Natija
1

Uch qadam va bir qadam. Noto'g'ri tartibda faqat WORKDIR keshdan olindi - RUN apk add esa har safar qaytadan ishlaydi.

Mening kompyuterimda bu farq 1.1 soniya va 2.5-3.1 soniya degani. Kichik misol uchun ko'p emas, lekin haqiqiy loyihada bog'liqliklarni o'rnatish bir necha daqiqa davom etadi - va bu har bir kommitda takrorlanadi.

To'g'ri tartibning to'liq chiqishi shunday ko'rinadi:

Natija
#5 [1/5] FROM docker.io/library/alpine:3.21@sha256:48b0309ca019...
#6 [2/5] WORKDIR /ilova
#6 CACHED
#7 [3/5] COPY bogliqliklar.txt .
#7 CACHED
#8 [4/5] RUN apk add --no-cache curl
#8 CACHED
#9 [5/5] COPY ilova.sh .

Faqat oxirgi qadam - o'zgargan kod - qaytadan bajarildi.

Umumiy naqsh - har bir tilda bir xil

Bog'liqlik ro'yxatini alohida ko'chiring, o'rnating, keyin kodni ko'chiring:

Natija
COPY <bog'liqlik ro'yxati> .
RUN  <o'rnatish buyrug'i>
COPY . .

Ro'yxat fayli tilga qarab boshqacha ataladi:

EkotizimFayl
Nodepackage.json, package-lock.json
Pythonrequirements.txt, poetry.lock
PHPcomposer.json, composer.lock
Gogo.mod, go.sum
RustCargo.toml, Cargo.lock
Javapom.xml

Kod o'zgaradi - bog'liqliklar o'rnatilmaydi. Ro'yxat o'zgaradi - o'shanda o'rnatiladi.

Keshni nima buzadi? #

SababIzoh
Ko'chirilgan fayl mazmuni o'zgardiCOPY uchun eng ko'p uchraydigani
Ko'rsatma matni o'zgardiHatto bo'sh joy qo'shilsa ham
Oldingi qadam buzildiZanjir pastga qarab uziladi
Asos obraz yangilandiFROM yangi digestga ishora qildi
--no-cache berildiAtaylab chetlab o'tish
COPY . . va kutilmagan kesh buzilishi

COPY . . butun konteksni kesh kalitiga kiritadi. Demak:

  • README.md ni tahrirlasangiz - kesh buziladi
  • Tahrirlovchingiz .swp fayl qoldirsa - kesh buziladi
  • .git/ ichida bitta bayt o'zgarsa - kesh buziladi

.dockerignore shuning uchun tezlik vositasi ham, nafaqat xavfsizlik chorasi.

Bir RUN ichida tozalash #

Qatlam yaratilgandan keyin undan fayl o'chirish obrazni kichraytirmaydi - fayl oldingi qatlamda qolaveradi.

Noto'g'ri:

DOCKERFILE
RUN apk add --no-cache curl
RUN rm -rf /var/cache/apk/*

To'g'ri:

DOCKERFILE
RUN apk add --no-cache curl \
    && rm -rf /var/cache/apk/*

Ikkinchi variantda o'chirish o'sha qatlamning ichida sodir bo'ladi, shuning uchun o'chirilgan fayl hech qachon qatlamga yozilmaydi.

Bu qoida barcha paket menejerlariga tegishli
Natija
apt-get update && apt-get install -y --no-install-recommends X \
    && rm -rf /var/lib/apt/lists/*

npm ci --omit=dev && npm cache clean --force

pip install --no-cache-dir -r requirements.txt

Ko'pchilik menejerda "keshni saqlama" bayrog'i bor - undan foydalaning.

Keshni ataylab chetlab o'tish #

Ba'zan kesh noto'g'ri javob beradi. Masalan RUN apk add curl ko'rsatmasi o'zgarmaydi, lekin repozitoriyda curl ning yangi versiyasi chiqqan - Docker buni bilmaydi va eski qatlamni beradi.

Natija
docker build --no-cache -t dokon:1.0 .

Bu barcha qadamni qaytadan bajaradi.

Ishlab chiqarish obrazini vaqti-vaqti bilan --no-cache bilan quring

Aks holda obrazingizda oylik eski tizim paketlari qolib ketishi mumkin - ular orasida yamoqlanmagan zaiflik ham bo'lishi mumkin.

Ko'p jamoalar CI da haftada bir marta --no-cache bilan qurishni rejalashtiradi.

11-bobdan boshlab bu mavzuga qaytamiz.

Kesh ham joy egallaydi #

Terminal
docker system df --format 'table {{.Type}}\t{{.Size}}' | grep -i build
Natija
Build Cache     26.01MB

Bu kichik misol uchun 26 MB. Faol loyihada kesh bir necha gigabayt ga yetishi mumkin.

Tozalash:

Natija
docker builder prune           # ishlatilmayotgan kesh
docker builder prune -af       # butun kesh
docker builder prune --filter until=168h   # bir haftadan eski

Xulosa #

  • Docker har ko'rsatma uchun kesh kaliti hisoblaydi; COPY uchun kalitga fayl mazmuni ham kiradi.
  • Kesh faqat pastga buziladi: bitta qadam o'zgarsa, undan keyingi hammasi qaytadan bajariladi.
  • Asosiy qoida: kam o'zgaradigan yuqorida, tez-tez o'zgaradigan pastda.
  • Bog'liqlik ro'yxatini alohida ko'chirib, o'rnatib, keyin kodni ko'chiring - bu naqsh har bir ekotizimda bir xil.
  • O'lchangan farq: to'g'ri tartibda 3 ta qadam keshdan, noto'g'risida 1 ta.
  • COPY . . butun kontekstni kesh kalitiga qo'shadi - README tahriri ham keshni buzadi.
  • .dockerignore - xavfsizlik chorasi ham, tezlik vositasi ham.
  • Fayl o'chirish o'sha RUN ichida bo'lsin; keyingi qatlamdagi rm obrazni kichraytirmaydi.
  • --no-cache keshni butunlay chetlab o'tadi; uni vaqti-vaqti bilan ishlating, aks holda eski paketlar qolib ketadi.
  • Qurish keshi ham disk egallaydi - docker builder prune bilan tozalanadi.
Amaliy topshiriq
  1. Ikkita Dockerfile yozing - to'g'ri va noto'g'ri tartibda.
  2. Ikkalasini quring, so'ng kodni o'zgartirib, grep -c CACHED bilan farqni o'lchang.
  3. Qurish vaqtini ikkala variant uchun o'lchab solishtiring.
  4. README.md ni tahrirlab, COPY . . li variantda kesh buzilishini kuzating.
  5. .dockerignore ga *.md qo'shib, o'sha tajribani takrorlang.
  6. Ikkita alohida RUN da apk add va rm yozib, obraz hajmini o'lchang.
  7. Ularni && bilan birlashtirib, hajmni yana o'lchang.
  8. --no-cache bilan qurib, vaqt farqini yozing.
  9. docker system df bilan qurish keshi hajmini kuzating.
  10. docker builder prune dan keyin qancha joy bo'shaganini aniqlang.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.