Multi-stage build
Production-д явуулах image-ийг аль болох жижиг байлгах хэрэгтэй. Гэхдээ build хийхэд олон хэрэгсэл (compiler, test runner, dev dependency) шаардлагатай. Эдгээрийг production image-д орхивол image томорч, аюулгүй байдал буурна.
Multi-stage build нь энэ асуудлыг шийддэг — нэг Dockerfile-д олон stage тодорхойлж, эцсийн image-д зөвхөн шаардлагатай файлуудыг оруулна.
Нэг stage-тай Dockerfile-ийн асуудал
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install # dev dependency-уудыг ч суулгана
COPY . .
RUN npm run build # TypeScript → JavaScript
CMD ["node", "dist/index.js"]
Энд юу болж байна вэ?
node_modulesдотор dev dependency-ууд бий (typescript, jest, eslint...)- Эцсийн image-д
src/TypeScript файлууд бий ч тэдгээр нь ажиллахад шаардлагагүй - Image хэмжээ: ~900MB
Multi-stage build — үндсэн бүтэц
# ── Stage 1: builder ──────────────────────────
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# ── Stage 2: production ───────────────────────
FROM node:20-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]
AS builder — stage-д нэр өгнө
COPY --from=builder — өмнөх stage-аас файл хуулна
Эцсийн image-д зөвхөн dist/ ба production dependency орно
Image хэмжээ: ~180MB → 5 дахин жижиг болно.
Go апп — жишээ
Go нь compiled хэл тул binary нэг файл болдог. Alpine ч шаардлагагүй:
# ── Stage 1: build ────────────────────────────
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server ./cmd/server
# ── Stage 2: minimal runtime ──────────────────
FROM scratch
COPY --from=builder /app/server /server
EXPOSE 8080
CMD ["/server"]
FROM scratch — хоосон base image, зөвхөн binary орно
Image хэмжээ: ~10MB
Python апп — жишээ
# ── Stage 1: dependencies ─────────────────────
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# ── Stage 2: production ───────────────────────
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "main.py"]
Development vs Production — нэг Dockerfile
--target flag-аар stage сонгоно:
FROM node:20 AS base
WORKDIR /app
COPY package*.json ./
# ── Development ───────────────────────────────
FROM base AS development
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]
# ── Builder ───────────────────────────────────
FROM base AS builder
RUN npm ci
COPY . .
RUN npm run build
# ── Production ────────────────────────────────
FROM node:20-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]
# Development container ажиллуулах
docker build --target development -t myapp:dev .
# Production image build хийх
docker build --target production -t myapp:prod .
Image хэмжээ харьцуулалт
| Арга | Node.js апп | | ------------------------ | ----------- | | node:20 нэг stage | ~950 MB | | node:20-alpine нэг stage | ~250 MB | | Multi-stage + alpine | ~120 MB | | Multi-stage + distroless | ~80 MB |
Distroless base image
Google-ийн distroless image нь shell, package manager зэрэг бүх зүйлийг хасаж, зөвхөн runtime орчин агуулна:
FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["dist/index.js"]
Shell байхгүй тул docker exec -it ... bash ажиллахгүй — debugging хийхэд хэцүү, гэхдээ production-д аюулгүй.
Дараагийн хичээлд:
Node.js Express аппликейшнийг бүрэн containerize хийх — development болон production Dockerfile бичих.