Image ni optimallash — alpine, slim, distroless

~12 daq · Docker · Dockerfile — o'z image ingiz

Muammodan boshlaylik

Image 1.2 GB. Har bir deploy da serverga yuklab olinadi — sekin tarmoqda bir necha daqiqa. Registry da 50 ta versiya — 60 GB. Avtomatik ko'paytirishda yangi server image ni yuklab olguncha foydalanuvchilar kutadi. Xavfsizlik skaneri image da 340 ta zaiflik topdi — ularning 95% i siz umuman ishlatmaydigan paketlarda.

Kichik image — tez, arzon va xavfsizroq.


1. Asos image ni tanlash

Asos Hajm Ichida Kamchilik
node:22 (bookworm) ~1.1 GB To'liq Debian, kompilyatorlar, git, curl Juda katta
node:22-slim ~200 MB Minimal Debian Ba'zi vositalar yo'q
node:22-alpine ~150 MB Alpine Linux musl — ba'zi native paketlar muammo
gcr.io/distroless/nodejs22-debian12 ~130 MB Faqat Node va zarur kutubxonalar Shell yo'q — debug qiyin

Alpine

Juda kichik distributiv (asosi ~8 MB). Paket menejeri — apk:

FROM node:22-alpine
RUN apk add --no-cache curl

Ehtiyot bo'ling: Alpine standart glibc o'rniga musl C kutubxonasini ishlatadi. Ko'p dasturlar uchun farqi yo'q, lekin:

  • Python ning ba'zi paketlari (numpy, pandas — eski versiyalar) tayyor "wheel" topmay, noldan kompilyatsiya qilinadi — build juda sekin
  • Ba'zi native Node modullari ishlamasligi mumkin
  • DNS va ba'zi tizim chaqiruvlarida nozik farqlar

Muammo chiqsa — -slim ga o'ting. Python uchun ko'pincha python:3.13-slim alpine dan yaxshiroq tanlov.

Distroless

Google ning image lari — faqat ilova ishlashi uchun kerak bo'lgan narsa: shell yo'q, paket menejeri yo'q, ls ham yo'q.

FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .

FROM gcr.io/distroless/nodejs22-debian12
WORKDIR /app
COPY --from=build /app .
USER nonroot
CMD ["src/index.js"]

Hujumchi konteyner ichiga kirsa ham — shell yo'q, vositalar yo'q. Lekin docker exec -it ... sh ham ishlamaydi — debug uchun :debug tegli varianti bor.


2. Faqat kerakli paketlar

# Debian / Ubuntu
RUN apt-get update \
 && apt-get install -y --no-install-recommends ca-certificates curl \
 && rm -rf /var/lib/apt/lists/*

# Alpine
RUN apk add --no-cache ca-certificates curl
  • --no-install-recommends — "tavsiya etilgan" qo'shimcha paketlarsiz (ko'pincha 2-3 barobar kamroq)
  • rm -rf /var/lib/apt/lists/* — paket ro'yxati keshi, xuddi shu RUN da (14-dars)
  • apk add --no-cache — keshni saqlamaslik

Node / Python:

RUN npm ci --omit=dev && npm cache clean --force
RUN pip install --no-cache-dir -r requirements.txt

3. Multi-stage

16-dars — eng katta ta'sir: yasash vositalari yakuniy image ga kirmaydi.


4. Image ni tahlil qilish

docker images ilova
docker history ilova           # qaysi qatlam qancha og'ir

dive — qatlamlarni interaktiv ko'rish vositasi:

docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive ilova:1.0

Har bir qatlamda qaysi fayllar qo'shilgani va "isrof qilingan joy" (keyingi qatlamda o'chirilgan fayllar) ko'rinadi.

Docker Desktop da ham — Images → image → qatlamlar.


5. Optimallashtirish — misol

Oldin (1.24 GB):

FROM node:22
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD npm start

Keyin (~165 MB):

# syntax=docker/dockerfile:1
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
RUN npm run build

FROM node:22-alpine
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev
COPY --from=build /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/main.js"]
O'zgarish Natija
node:22 → node:22-alpine ~900 MB kamroq
Multi-stage Dev paketlar va manba kod yo'q
npm install → npm ci --omit=dev Faqat production paketlar
.dockerignore (15-dars) node_modules, .git kontekstda yo'q
CMD npm start → exec shakli node Signallar to'g'ri, npm jarayoni yo'q
USER node Root siz

Qanchalik kichraytirish kerak?

Har bir megabayt uchun kurashish shart emas. Muvozanat:

  • 1 GB+ → 200 MB — katta foyda, minimal mehnat (asos image + multi-stage). Doim qiling
  • 200 MB → 50 MB — foydali, lekin alpine/distroless cheklovlari bilan
  • 50 MB → 45 MB — odatda vaqtga arzimaydi

Debug qila olish va barqarorlik — oxirgi bir necha megabaytdan muhimroq.


Nima uchun shunday?

Nima uchun kichik image xavfsizroq?

Chunki xavfsizlik zaifligi — mavjud dasturda bo'ladi. To'liq Debian image da yuzlab paket bor: compiler lar, tarmoq vositalari, kutubxonalar. Ularning har birida vaqt o'tishi bilan zaiflik topiladi — va skaner ularni ko'rsatadi, garchi ilovangiz ulardan foydalanmasa ham. Hujumchi esa konteynerga kirsa — curl, wget, gcc uning qo'lida qurol bo'ladi. Image da yo'q narsa — buzilmaydi va qurol bo'lmaydi. "Hujum yuzasini kamaytirish" — xavfsizlikning asosiy tamoyili.


Xulosa

Eslab qoling:

  • Asos: slim — xavfsiz tanlov; alpine — kichik, lekin musl; distroless — eng kichik, shell siz
  • Python uchun ko'pincha -slim > -alpine
  • --no-install-recommends, kesh tozalash — xuddi shu RUN da
  • npm ci --omit=dev, pip --no-cache-dir
  • Multi-stage — eng katta ta'sir
  • docker history, dive — qayerda joy ketayotganini ko'rish
  • 1 GB → 200 MB doim; undan keyin — debug va barqarorlik bilan muvozanat

Keyingi dars

18-dars: 3-bo'lim mashqlari — Node.js API uchun Dockerfile