Dockerfile bo‘yicha eng yaxshi amaliyotlar: tez va toza obrazlar
Amaliyot3 daqInnovialabs tahririyati
Qisqacha
Yaxshi Dockerfile bog‘liqlik fayllarini koddan oldin nusxalaydi, versiyasi qotirilgan ixcham bazaviy obrazdan foydalanadi, ortiqchani .dockerignore orqali chiqarib tashlaydi va ilovani root bo‘lmagan foydalanuvchidan ishga tushiradi.
Qisqacha: Dockerfile’ni nima yaxshi qiladi
Besh qoidaga amal qilsangiz, tez va toza obraz olasiz:
- Qatlamlar tartibi: kam o‘zgaradigan narsalar yuqorida, tez-tez o‘zgaradiganlar pastda.
- Aniq versiyali ixcham bazaviy obraz.
- Obrazga keraksiz narsalar va sirlar tushmasligi uchun .dockerignore.
- root o‘rniga imtiyozsiz foydalanuvchi.
- Bazaviy obraz va bog‘liqliklarning qotirilgan versiyalari.
Qatlamlar tartibi va kesh
Docker obrazni qatlamma-qatlam yig‘adi va har birini keshlaydi. Agar qatlam o‘zgarsa, undan keyingi barcha qatlamlar qayta yig‘iladi. Shuning uchun avval faqat bog‘liqlik fayllarini nusxalab o‘rnating, keyin esa manba kodini.
Yomon: boshida COPY . .. Kodga har qanday tuzatish barcha paketlarni qayta o‘rnatishga majbur qiladi.
Yaxshi: package.json va lock fayl alohida, o‘rnatish, keyin kod. Bog‘liqliklar o‘zgarmaguncha o‘rnatish keshdan olinadi.
Yana maslahatlar:
- Bog‘liq buyruqlarni bitta
RUNga birlashtiring va paket menejeri keshini o‘sha qatlamda tozalang. - Faqat yig‘ish uchun kerak bo‘lgan vositalarni yakuniy obrazga qo‘shmang — multi-stage builddan foydalaning.
Bazaviy obrazni tanlash
| Variant | Afzalliklari | Kamchiliklari |
|---|---|---|
To‘liq (node:22, python:3.12) | Hammasi tayyor | Katta hajm, ko‘proq zaifliklar |
Slim (-slim) | Kichikroq, Debian asosida | Ba’zan tizim paketlari yetishmaydi |
Alpine (-alpine) | Juda kichik | glibc o‘rniga musl, native modullar bilan muammolar bo‘lishi mumkin |
| Distroless | Minimal hujum yuzasi | Shell yo‘q, debug qilish qiyinroq |
Ko‘pchilik ilovalar uchun oqilona boshlanish — aniq versiyaning rasmiy tegi bilan slim yoki alpine.
.dockerignore
Usiz build kontekstiga hamma narsa tushadi: node_modules, .git, lokal .env. Yig‘ish sekinlashadi, obraz kattalashadi, sirlar oshkor bo‘lishi mumkin.
node_modules
.git
.env
*.log
dist
__pycache__
.venv
Node.js uchun misol
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./node_modules
COPY --chown=node:node . .
USER node
EXPOSE 3000
CMD ["node", "server.js"]
Bu yerda nima muhim:
- Birinchi bosqich bog‘liqliklarni lock fayl bo‘yicha
npm ciorqali o‘rnatadi — natija takrorlanadigan bo‘ladi. - Yakuniy bosqich faqat tayyor
node_modulesva kodni oladi. USER node— rasmiy obrazdagi o‘rnatilgan imtiyozsiz foydalanuvchi.CMDexec shaklida (massiv) — jarayon to‘xtatish signallarini to‘g‘ri qabul qiladi.
Agar loyihaga yig‘ish kerak bo‘lsa (TypeScript, frontend), alohida build bosqichini qo‘shing va yakuniy obrazga faqat natijani nusxalang.
Python uchun misol
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
RUN useradd --create-home appuser
COPY --chown=appuser:appuser . .
USER appuser
EXPOSE 8000
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]
Bu yerda nima muhim:
requirements.txtkoddan oldin nusxalanadi — o‘rnatish keshlanadi.--no-cache-dirobrazda pip keshini qoldirmaydi.PYTHONUNBUFFERED=1— loglar darhol konteyner stdout’iga tushadi.- Ilova alohida
appuserfoydalanuvchisidan ishlaydi.
Keng tarqalgan xatolar
- Bazaviy obraz uchun
latesttegi — yig‘ish sizdan bexabar o‘zgaradi. ENVyokiCOPYichidagi sirlar — ular o‘chirilgandan keyin ham obraz qatlamlarida qoladi.apt-get updatevaapt-get installalohidaRUNlarda — indeks keshi eskiradi.- Prodakshnda kompilyatorlar va dev-bog‘liqliklar bilan bitta ulkan obraz.