Как работает multi-stage сборка в Docker?

«Как работает multi-stage сборка в Docker?» — вопрос из категории DevOps, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Multi-stage сборка — это техника в Docker, позволяющая использовать несколько инструкций FROM в одном Dockerfile для создания промежуточных образов (stages) и копирования только необходимых артефактов в финальный образ. Это резко уменьшает размер итогового образа, исключая инструменты сборки, исходный код и промежуточные файлы.

Как это работает:

  1. Каждая инструкция FROM начинает новый этап (stage).
  2. На промежуточных этапах можно устанавливать компиляторы, зависимости и выполнять сборку.
  3. С помощью COPY --from=<stage_name> артефакты (например, скомпилированные бинарники или зависимости) копируются из промежуточного образа в финальный.
  4. В финальный образ попадает только содержимое последнего этапа.

Пример для Go-приложения:

# Stage 1: Сборка
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /myapp

# Stage 2: Финальный минимальный образ
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /myapp .
CMD ["./myapp"]

Преимущества:

  • Меньший размер образа: Финальный образ содержит только рантайм и приложение, а не SDK, компиляторы или кеш пакетов.
  • Улучшенная безопасность: В продакшене меньше атакующей поверхности, так как отсутствуют инструменты для сборки.
  • Четкое разделение: Логика сборки и логика выполнения изолированы.