Dockerfile
Урок 3~9 минут
Multi-stage builds: маленькие продакшн-образы
Multi-stage build — одна из самых мощных возможностей Docker. Позволяет собирать приложение в одном образе и запускать в другом, намного меньшем.
Проблема
dockerfile
FROM golang:1.22 # ~800MB с инструментами сборки
WORKDIR /app
COPY . .
RUN go build -o server .
CMD ["./server"]Итог: образ весит ~800MB. А в нём нужен только бинарник server (~10MB).
Решение: multi-stage
dockerfile
# Стадия 1: сборка
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server .
# Стадия 2: финальный образ
FROM scratch
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE 8080
CMD ["/server"]Итог: образ ~15MB. Инструменты сборки остались только в промежуточном образе.
Попробуй в симуляции
Node.js: dev vs production
dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json .
CMD ["node", "dist/index.js"]devDependencies (TypeScript, Jest, ESLint) в финальный образ не попадают.
Именованные стадии
dockerfile
FROM node:20 AS build-stage
# ...
FROM nginx:alpine AS prod-stage
COPY --from=build-stage /app/dist /usr/share/nginx/htmlКопировать можно из любой стадии: --from=build-stage или --from=0 (по индексу).
Целевая стадия
bash
# Собрать только до конкретной стадии (полезно для тестирования)
docker build --target builder -t app:builder .
docker build --target runner -t app:latest .Размеры сравним
| Образ | Размер |
|---|---|
| golang:1.22 (без multi-stage) | ~850MB |
| golang:1.22-alpine | ~330MB |
| FROM scratch (multi-stage) | ~10-20MB |
| node:20 (без multi-stage) | ~1.1GB |
| node:20-alpine (prod deps) | ~150MB |
| nginx + static (SPA) | ~25MB |
Alpine vs slim vs scratch
ubuntu:22.04— полноценный ubuntu, ~80MBdebian:bookworm-slim— минимальный debian, ~75MBalpine:3.19— минимальный linux, ~7MB, musl libcscratch— пустой, 0MB, только статически скомпилированные бинарники
В следующем модуле — Docker Compose для многоконтейнерных приложений.
Multi-stage: собираем в тяжёлом образе с инструментами, копируем результат в лёгкий. Go бинарник 50MB → образ 15MB.
⚡
Multi-stage build: размер образаОБРАЗ (один Dockerfile)
~767 MB — go toolchain в продакшне
⚠️ Go компилятор, source code, все build tools — всё попало в продакшн образ
# Dockerfile
FROM golang:1.22 AS builder
WORKDIR /app && COPY . . && go build -o server .
FROM scratch
COPY --from=builder /app/server /server
CMD ["/server"]
🎯
Миссия 1 из 3
Зачем нужен multi-stage build?