Ответ
Multi-stage builds — это функция Docker, позволяющая использовать несколько инструкций FROM в одном Dockerfile. Каждая стадия начинается с нового базового образа и может копировать артефакты из предыдущих стадий. Главная цель — создать минимальный итоговый образ, не содержащий инструментов сборки и промежуточных файлов.
Проблема, которую это решает: Традиционный Dockerfile для компилируемого языка (Go, C++) включает в финальный образ компилятор, исходный код и все зависимости для сборки, что сильно увеличивает размер и поверхность для атак.
Пример для Go-приложения:
# --- СТАДИЯ 1: Сборка (builder) ---
# Используем полный образ с Go и компилятором
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Компилируем статичный бинарник
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# --- СТАДИЯ 2: Запуск (final) ---
# Используем пустой минимальный образ
FROM scratch
WORKDIR /root/
# Копируем ТОЛЬКО скомпилированный бинарник из стадии 'builder'
COPY --from=builder /app/main .
# Копируем SSL-сертификаты (необходимы для многих сетевых вызовов)
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Запускаем приложение
CMD ["./main"]
Преимущества:
- Размер: Итоговый образ уменьшается с ~350 МБ (полный Go-образ) до ~10 МБ (один бинарник).
- Безопасность: В финальном образе нет компилятора, shell или пакетного менеджера, что сокращает векторы атак.
- Чистота: В образе только то, что нужно для запуска приложения.