Ответ
Многоэтапная сборка (multi-stage build) — это возможность использовать несколько инструкций FROM в одном Dockerfile для разделения процесса сборки приложения и создания финального образа.
Основная цель — уменьшить размер итогового Docker-образа, исключив из него зависимости и инструменты, необходимые только для сборки (компиляторы, SDK, dev-зависимости).
Как это работает:
- Первый этап (сборщик): Используется базовый образ со всеми инструментами. В нем компилируется код, устанавливаются зависимости, собираются артефакты.
- Второй этап (финальный): Используется минималистичный базовый образ (например,
alpineили-slim). В него копируются только необходимые для запуска артефакты из первого этапа с помощью флага--from.
Пример для Python-приложения:
# --- Этап 1: Сборка зависимостей ---
# Используем полный образ Python для установки пакетов
FROM python:3.9 as builder
WORKDIR /app
# Создаем виртуальное окружение
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Устанавливаем зависимости
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# --- Этап 2: Финальный образ ---
# Используем легковесный образ для запуска
FROM python:3.9-slim
WORKDIR /app
# Копируем только виртуальное окружение с зависимостями из этапа 'builder'
COPY --from=builder /opt/venv /opt/venv
# Копируем исходный код
COPY . .
# Указываем путь к исполняемым файлам из venv
ENV PATH="/opt/venv/bin:$PATH"
# Запускаем приложение
CMD ["python", "app.py"]
Преимущества:
- Уменьшение размера образа: Финальный образ не содержит ненужных слоев с инструментами сборки.
- Повышение безопасности: Меньше установленных пакетов — меньше потенциальных уязвимостей.
- Упрощение CI/CD: Весь процесс сборки описан в одном
Dockerfile.
Ответ 18+ 🔞
Да ты посмотри, какая хитрая штука придумана, блядь! Многоэтапная сборка, называется. Это когда в одном Dockerfile можно нагородить несколько этапов, и каждый из них — как отдельная, блядь, вселенная.
Основная фишка, понятное дело, — чтобы итоговый образ не весил как чугунный мост, ёпта. Выкинуть нахуй всё лишнее: эти твои компиляторы, SDK, тонны dev-зависимостей, которые нужны только чтобы собрать приложение, а потом они как манда с ушами торчат в финальном контейнере и места жрут.
Работает это, блядь, как по нотам:
- Этап первый, сборщик: Берёшь жирный образ, забитый всеми инструментами до упора. Тут ты свой код компилируешь, зависимости ставишь — в общем, творишь, что хочешь.
- Этап второй, финальный: Берёшь образ-голыш, какой-нибудь
alpineтощий. И копируешь в него из первого этапа только готовые артефакты, что для запуска нужны. Всё остальное — на свалку истории, в рот меня чих-пых!
Смотри, как для Python-приложения выглядит:
# --- Этап 1: Сборка зависимостей ---
# Тут живёт жирный питон со всеми потрохами
FROM python:3.9 as builder
WORKDIR /app
# Делаем виртуальное окружение, чтоб не засорять систему
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Ставим зависимости в это окружение
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# --- Этап 2: Финальный образ ---
# А тут уже питон-скелет, голый и тощий
FROM python:3.9-slim
WORKDIR /app
# Волшебство! Тащим из первого этапа только готовый venv
COPY --from=builder /opt/venv /opt/venv
# Копируем свой код
COPY . .
# Пути прописываем
ENV PATH="/opt/venv/bin:$PATH"
# Поехали!
CMD ["python", "app.py"]
И какие, блядь, плюсы?
- Размер, ёбта! Финальный образ легче пуха. Никакого хлама.
- Безопасность, мать её. Меньше пакетов — меньше дырок, куда всякие пидарасы могут пролезть.
- CI/CD радуется. Всё в одном файле, не надо городить огород из скриптов. Красота, блядь!