← Назад к вопросам

Что такое multistage сборка Docker?

2.0 Middle🔥 212 комментариев
#Контейнеризация и DevOps

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Multistage сборка Docker (Multi-stage build)?

Multistage сборка (мультистейдж, многоэтапная сборка) — это мощная техника в Docker, позволяющая использовать несколько этапов (образов FROM) в одном Dockerfile для оптимизации итогового образа. Ключевая цель — отделить среду сборки (build environment) от финального рантайм-образа (runtime image), чтобы итоговый контейнер содержал только необходимые для работы артефакты (бинарники, зависимости), без инструментов компиляции, исходного кода или промежуточных файлов.

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

В одном Dockerfile вы можете определить несколько этапов с помощью директивы FROM. Каждый этап начинается с нового базового образа и может копировать артефакты из предыдущих этапов. В итоговый образ попадает только содержимое последнего этапа.

Базовый пример для Go-приложения:

Представьте типичный сценарий: вам нужно скомпилировать Go-приложение (требуется Go SDK), а запустить — в минимальном образе (например, alpine).

Dockerfile без multistage (проблемный подход):

FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o myapp main.go

# Финальный образ
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

В этом примере есть два этапа:

  1. Этап builder: Использует полный образ golang:1.21-alpine (~350 МБ) для компиляции. Здесь выполняется загрузка зависимостей и сборка бинарника myapp.
  2. Финальный этап: Начинается с чистого alpine:latest (~5 МБ). С помощью COPY --from=builder копируется только скомпилированный бинарник из этапа builder. Инструменты Go, исходный код, промежуточные объектные файлы — всё это остаётся в первом этапе и не попадает в финальный образ.

Итоговый образ будет весить ~10 МБ (Alpine + бинарник) вместо ~350 МБ, что критично для скорости деплоя, безопасности и эффективности использования реестров.

Преимущества multistage сборки

  • Резкое уменьшение размера образа: Как показано выше, из образа удаляются все инструменты сборки, исходный код, временные файлы.
  • Улучшенная безопасность: В финальном образе меньше компонентов → меньше поверхность для атак (меньше CVEs, уязвимых пакетов).
  • Оптимизация кеширования слоёв: Каждый этап имеет собственный кеш. Изменения в исходном коде не инвалидируют кеш для этапа установки зависимостей, если go.mod не менялся.
  • Упрощение Dockerfile: Нет необходимости поддерживать отдельные скрипты для чистки или сложные цепочки команд.
  • Гибкость: Можно использовать разные базовые образы для разных этапов (например, golang для сборки, distroless или scratch для рантайма).

Продвинутые приёмы

Использование именованных этапов

Этапам можно давать имена ( AS <name>), чтобы явно ссылаться на них при копировании.

FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o app .

FROM gcr.io/distroless/static-debian12 AS final
COPY --from=builder /app/app /
CMD ["/app"]

Несколько этапов для разных артефактов

Иногда нужно подготовить несколько артефактов (бинарник, миграции, статика).

FROM node:18 AS frontend-builder
WORKDIR /app/frontend
COPY frontend/ .
RUN npm ci && npm run build

FROM golang:1.21 AS backend-builder
WORKDIR /app/backend
COPY backend/ .
RUN go build -o api .

FROM alpine:latest
WORKDIR /app
COPY --from=frontend-builder /app/frontend/dist ./static
COPY --from=backend-builder /app/backend/api .
CMD ["./api"]

Этап только для зависимостей (для улучшения кеширования)

Отдельный этап для скачивания зависимостей ускоряет повторные сборки.

FROM golang:1.21 AS deps
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

FROM deps AS builder
COPY . .
RUN go build -o myapp .

FROM alpine:latest
COPY --from=builder /app/myapp .
CMD ["./myapp"]

Заключение

Multistage сборка — это must-have практика для создания production-образов. Для Go-разработчика это особенно актуально, учитывая статическую линковку и возможность создавать самодостаточные бинарники. Результат — минимальные, безопасные и быстрые в развёртывании контейнеры. Все современные CI/CD системы и Docker Engine (версии > 17.05) поддерживают эту функциональность. Игнорирование этого подхода ведёт к раздутым образам, повышенным рискам безопасности и неэффективному использованию ресурсов.

Что такое multistage сборка Docker? | PrepBro