Docker multi-stage build: image hajmini 40 barobar kichraytiramiz
Go ilovangizning Docker image'i 900 MB'mi? Multi-stage build yordamida uni 20 MB atrofiga tushirish, xavfsizlikni oshirish va deployni tezlashtirish bo'yicha amaliy misollar.

Muammo
Ko'pchilik Dockerfile'ni shunday yozadi:
FROM golang:1.23
WORKDIR /app
COPY . .
RUN go build -o server .
CMD ["./server"]
Bu ishlaydi. Lekin yakuniy image ichida butun Go kompilyatori, kesh, manba kod va keraksiz utilitalar qoladi. Hajm osongina 900 MB dan oshib ketadi. Bu quyidagilarga olib keladi:
- Sekin deploy: har safar yuzlab megabayt registry'ga yuklanadi va serverga tortiladi.
- Katta hujum yuzasi: image'dagi har bir ortiqcha paket potensial zaiflik.
- Ortiqcha xarajat: disk, trafik va CI vaqti behuda ketadi.
Yechim: multi-stage build
G'oya oddiy: bitta bosqichda ilovani quramiz, boshqasida faqat tayyor binarni ishga tushiramiz.
# 1-bosqich: build
FROM golang:1.23 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o server .
# 2-bosqich: runtime
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/server /server
USER nonroot:nonroot
ENTRYPOINT ["/server"]
Natija: image hajmi taxminan 15–25 MB.
Nimalar o'zgardi?
AS builder: birinchi bosqichga nom beramiz, keyin undan fayl olamiz.go.modalohida nusxalanadi: bog'liqliklar kodga qaraganda kamroq o'zgaradi, shuning uchun Docker bu qatlamni keshlaydi va build tezlashadi.CGO_ENABLED=0: statik binar hosil bo'ladi, tashqi C kutubxonalariga bog'liq emas.-ldflags="-s -w": debug ma'lumotlari olib tashlanadi, binar kichrayadi.distroless: ichida shell ham, paket menejeri ham yo'q. Faqat sizning ilovangiz.USER nonroot: konteyner root huquqisiz ishlaydi.
Eslatma: distroless'da shell yo'q, shuning uchun
docker exec -it ... shishlamaydi. Debug kerak bo'lsa,static-debian12:debugvariantidan foydalaning.
Python uchun ham ishlaydimi?
Ha. Builder bosqichida wheel'larni yig'ib, runtime uchun slim image olamiz:
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /wheels /wheels
RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels
COPY . .
CMD ["python", "main.py"]
Bu yerda yutuq Go'dagidek katta emas. Lekin kompilyatorlar va build vositalari yakuniy image'ga tushmaydi, bu esa hajm va xavfsizlik uchun foydali.
Xulosa
Multi-stage build eng oson optimizatsiyalardan biri: Dockerfile'ga 5 daqiqa vaqt sarflaysiz, har bir deployda esa vaqt va xavfsizlik yutasiz. Agar loyihangizda hali bitta FROM bo'lsa, bugun sinab ko'ring va docker images natijasini solishtiring.