İyi bir Dockerfile nasıl yazılır? Multi-stage build ne işe yarar?
Cevap
Örnek: Node.js için multi-stage Dockerfile
# 1. aşama: bağımlılıklar ve build
FROM node:20-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build && npm prune --omit=dev
# 2. aşama: yalnızca çalışma zamanı
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build --chown=node:node /app/node_modules ./node_modules
COPY --from=build --chown=node:node /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]Multi-stage build, derleyici, dev bağımlılıkları ve kaynak kodu gibi yalnızca build sırasında gereken her şeyi ilk aşamada bırakır. Son image yalnızca çalışması gerekenleri içerir: daha küçük boyut, daha hızlı dağıtım, daha az güvenlik açığı yüzeyi. Go gibi derlenen dillerde son aşama distroless veya scratch olabilir.
Best practice'ler
- Layer cache'i doğru kullanın: az değişen dosyaları önce kopyalayın. Önce
package.jsonkopyalanıpnpm ciçalıştırılır; böylece yalnızca kod değiştiğinde bağımlılıklar yeniden kurulmaz. - Küçük ve sabit base image:
node:20-alpineveya-slim;latestetiketi yerine sürüm belirtin. - `.dockerignore`:
node_modules,.git,.env, test çıktıları image'a girmesin. - Root olarak çalıştırmayın:
USER nodeveya kendi oluşturduğunuz kullanıcı. - RUN komutlarını birleştirin ve aynı katmanda temizlik yapın:
apt-get update && apt-get install -y x && rm -rf /var/lib/apt/lists/* - Secret'ları image'a gömmeyin:
ENV API_KEY=...veyaCOPY .envimage geçmişinde kalır. Build sırasında gerekiyorsaRUN --mount=type=secretkullanın. - Exec form CMD:
CMD ["node", "server.js"]. Shell form (CMD node server.js) sinyalleri sürece iletmez;docker stopsonrası graceful shutdown çalışmaz. - Image'ları
docker scoutveyatrivyile güvenlik açıklarına karşı tarayın.
İlgili Docker & DevOps soruları
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.