Multi-stage сборка Dockerfile: уменьшение размера production-образов
- Production-образы весят сотни мегабайт или гигабайты (содержат компиляторы, исходный код и SDK).
- Высокая длительность скачивания образов в CI/CD пайплайнах (CI pull/push latency).
- Наличие уязвимостей в пакетах этапа сборки, попавших в production-окружение.
1. Базовый шаблон Multi-stage для компилируемых языков (Golang)
# --- СТАДИЯ 1: Сборка ---
FROM golang:1.22-alpine AS builder
WORKDIR /app
RUN apk add --no-cache git ca-certificates
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /app/server .
# --- СТАДИЯ 2: Финальный минимальный образ ---
FROM scratch
WORKDIR /app
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/server /app/server
USER 10001:10001
ENTRYPOINT ["/app/server"]2. Multi-stage для Node.js приложений
# Стадия сборки зависимостей
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# Финальный контейнер
FROM node:20-alpine
WORKDIR /app
COPY --from=build /app/node_modules ./node_modules
COPY . .
USER node
CMD ["node", "server.js"]3. Проверка и сравнение слоев
docker build -t my_optimized_app:v1 .
docker history my_optimized_app:v1 Частые вопросы (FAQ)
Что дает флаг -ldflags='-w -s' при сборке Go в Docker?
Он удаляет отладочные символы DWARF (-w) и таблицу символов (-s), уменьшая размер бинарного файла на 30-50% без потери функциональности.
Зачем копировать go.mod и package.json до копирования остального кода?
Это позволяет эффективно использовать слой кэширования Docker: зависимости перекачиваются только при изменении файлов манифестов, а не при каждой правке исходного кода.