← Назад к вопросам
Что такое Multi-stage builds в Docker?
1.8 Middle🔥 182 комментариев
#MLOps и инфраструктура
Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Multi-stage builds в Docker
Multi-stage build — это техника оптимизации Docker образов, позволяющая использовать несколько FROM инструкций в одном Dockerfile. Это помогает уменьшить размер финального образа, исключив build dependencies из production образа.
Проблема: однозвёздный build
# Плохо: всё в одном образе
FROM python:3.11
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]
# Размер: ~800MB
# В образе: Python, pip, build tools, source код — всё
Решение: multi-stage build
# Stage 1: Builder
FROM python:3.11 as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# Stage 2: Runtime
FROM python:3.11-slim
WORKDIR /app
# Копируем только необходимые файлы из builder
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "main.py"]
# Размер: ~200MB (уменьшился в 4 раза!)
Как это работает
Фаза 1 (Builder)
┌─────────────────────────────────┐
│ FROM python:3.11 │
│ INSTALL pip, build tools │ ← всё это
│ COPY requirements.txt │
│ RUN pip install ... │
│ COPY source code │ временно
└─────────────────────────────────┘
↓ (удаляется)
Фаза 2 (Runtime)
┌─────────────────────────────────┐
│ FROM python:3.11-slim │
│ COPY --from=builder /root/.local │ ← копируем только
│ COPY source code │ установленные
│ CMD ["python", "main.py"] │ зависимости
└─────────────────────────────────┘
↓
Финальный образ (~200MB)
Практический пример: Go приложение
# Stage 1: Compilation
FROM golang:1.21 as builder
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o app main.go
# Stage 2: Runtime
FROM alpine:latest
WORKDIR /app
COPY --from=builder /build/app .
CMD ["./app"]
# Builder: ~800MB (golang компилятор, исходный код)
# Runtime: ~5MB (только бинарник + alpine)
Практический пример: Node.js
# Stage 1: Dependencies
FROM node:18 as dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# Stage 2: Build (если есть TypeScript/bundling)
FROM node:18 as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 3: Runtime
FROM node:18-alpine
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json .
EXPOSE 3000
CMD ["node", "dist/index.js"]
# dependencies: ~400MB
# builder: ~900MB
# runtime: ~150MB (только production deps + built code)
Преимущества
1. Размер образа: ↓ 50-80% (удаляются build tools)
2. Скорость pull: быстрее скачивается
3. Безопасность: меньше потенциальных уязвимостей
4. Чистота: builder инструменты не в production
Named stages
FROM node:18 as dev-stage
RUN npm install -g nodemon
FROM node:18 as test-stage
COPY --from=dev-stage /app /app
RUN npm run test
FROM node:18-alpine as prod
COPY --from=test-stage /app/dist ./dist
CMD ["node", "dist/index.js"]
# Строим конкретный stage:
# docker build --target prod -t myapp:latest .
Условное копирование (Docker BuildKit)
# Требует: DOCKER_BUILDKIT=1
FROM golang:1.21 as builder
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -o app main.go
# Кэшируется между builds, экономит время
Сравнение размеров
# Без multi-stage
$ docker build -t app:v1 .
$ docker images app:v1
# app:v1 1.2GB
# С multi-stage
$ docker build --target prod -t app:v2 .
$ docker images app:v2
# app:v2 250MB (в 5 раз меньше!)
Best Practices
# 1. Используй Alpine для runtime (если возможно)
FROM python:3.11-alpine
# 2. Раздели builder и runtime
FROM golang:1.21 as builder
# ... compile ...
FROM alpine:latest
COPY --from=builder /app/binary .
# 3. Минимизируй слои в runtime
FROM alpine
RUN apk add --no-cache curl ca-certificates
COPY --from=builder /app/binary .
# 4. Используй BuildKit для кэширования
export DOCKER_BUILDKIT=1
docker build .
Резюме
Multi-stage builds:
- Уменьшают размер образа на 50-90%
- Разделяют build и runtime слои
- Улучшают безопасность (меньше инструментов в production)
- Синтаксис:
COPY --from=stage_name /path . - Essential для production Docker образов