За счет чего достигается Multi-stage
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
За счет чего достигается Multi-stage в Docker
Multi-stage (многостадийная сборка) в Docker — это методика создания оптимизированных Docker-образов за счет использования нескольких этапов (стадий) сборки внутри одного Dockerfile. Ключевая идея заключается в разделении среды сборки (build environment) и финальной среды выполнения (runtime environment), что позволяет исключить из итогового образа ненужные инструменты, зависимости и артефакты промежуточной сборки.
Основные механизмы достижения Multi-stage
-
Несколько инструкций
FROMв одном Dockerfile
Каждая инструкцияFROMначинает новую стадию сборки. Вы можете дать стадиям имена (алиасы) с помощью ключевого словаAS, чтобы ссылаться на них в последующих инструкциях.# Стадия сборки (builder stage) FROM golang:1.21-alpine AS builder WORKDIR /app COPY . . RUN go build -o myapp . # Финальная стадия (runtime stage) FROM alpine:latest WORKDIR /root/ COPY --from=builder /app/myapp . CMD ["./myapp"] -
Избирательное копирование артефактов между стадиями
ИнструкцияCOPY --from=<stage_name>позволяет копировать только необходимые файлы из предыдущих стадий. Это основной инструмент для "очистки" финального образа.COPY --from=builder /app/compiled-binary /usr/local/bin/ -
Использование разных базовых образов для разных стадий
- Для стадии сборки: Используются "тяжелые" образы с полным набором инструментов (компиляторы, библиотеки разработки, пакетные менеджеры).
Примеры: `golang:latest`, `node:18`, `python:3.11-slim` с установленными build-зависимостями.
- Для финальной стадии: Используются минималистичные образы, содержащие только необходимые для запуска приложения компоненты.
Примеры: `alpine:latest` (всего 5 МБ), `distroless` образы от Google, `scratch` (пустой образ).
Конкретные примеры оптимизаций
Для Go-приложений:
# Стадия сборки с полным Go SDK
FROM golang:1.21 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
# Финальная стадия на основе scratch (минимальный возможный образ)
FROM scratch
COPY --from=builder /src/app /app
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
CMD ["/app"]
Для Node.js приложений:
# Стадия сборки с установкой всех зависимостей и сборкой
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Финальная стадия только с production-зависимостями
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/index.js"]
Для приложений на языках со статической компиляцией (Rust, C++) можно использовать даже образ scratch, что дает минимальный размер:
FROM rust:1.70 AS builder
WORKDIR /usr/src/app
COPY . .
RUN cargo build --release
FROM scratch
COPY --from=builder /usr/src/app/target/release/myapp /
CMD ["/myapp"]
Преимущества Multi-stage сборки
-
Значительное уменьшение размера финального образа
Пример: Go-приложение, собранное сgolang:1.21(~1 ГБ) и развернутое наalpine:latest(~5 МБ), экономит ~995 МБ. -
Повышение безопасности
- В финальном образе отсутствуют компиляторы, отладчики, пакетные менеджеры
- Меньше surface area для потенциальных атак
- Можно использовать минималистичные образы без shell (например,
distroless)
-
Упрощение зависимостей
- Четкое разделение development и production зависимостей
- Исключаются конфликты версий инструментов сборки и среды выполнения
-
Снижение затрат на хранение и передачу образов
Меньшие образы быстрее загружаются из registry, экономят дисковое пространство и сетевой трафик.
Продвинутые техники Multi-stage
-
Использование стадий как кэша
Вы можете повторно использовать стадии для кэширования зависимостей:FROM node:18 AS deps WORKDIR /app COPY package*.json ./ RUN npm ci FROM deps AS builder COPY . . RUN npm run build -
Параллельная сборка нескольких артефактов
В разных стадиях можно собирать разные компоненты системы. -
Использование внешних образов как источников
COPY --from=nginx:alpine /etc/nginx/nginx.conf /etc/nginx/nginx.conf
Практические рекомендации
- Всегда именуйте стадии (
AS builder) для удобства сопровождения - Копируйте только необходимые артефакты — избегайте
COPY --from=builder /app ./ - Для скриптовых языков (Python, PHP) используйте отдельную стадию для установки зависимостей компиляции
- Тестируйте финальный образ на наличие уязвимостей с помощью
docker scoutилиtrivy
Multi-stage сборка стала стандартом де-факто для production-образов, сокращая размеры образов в 5-10 раз и значительно повышая безопасность контейнеризированных приложений. Это обязательный навык для современного DevOps-инженера, непосредственно влияющий на эффективность CI/CD пайплайнов и инфраструктуры контейнеров.