Ответ
Multi-stage Dockerfile — это мощный инструмент для создания оптимизированных и безопасных Docker-образов. Он позволяет разделить процесс сборки приложения на несколько этапов, используя промежуточные образы для выполнения задач (например, компиляции, установки зависимостей), а затем копируя только необходимые артефакты в финальный, минимальный образ.
Почему это важно?
- Уменьшение размера образа: Финальный образ не содержит инструментов сборки, временных файлов и ненужных зависимостей.
- Улучшение безопасности: Меньше компонентов в финальном образе означает меньшую поверхность атаки.
- Ускорение сборки: Кэширование слоев на разных этапах может ускорить повторные сборки.
Пример для Python-приложения:
Предположим, у нас есть requirements.txt и app.py.
# --- Этап 1: Сборка и установка зависимостей (builder) ---
# Используем более полный образ для установки зависимостей
FROM python:3.9-slim as builder
# Устанавливаем рабочую директорию
WORKDIR /app
# Копируем файл зависимостей
COPY requirements.txt .
# Устанавливаем зависимости в пользовательскую директорию
# Это позволяет легко скопировать их на следующем этапе
RUN pip install --user -r requirements.txt
# --- Этап 2: Финальный образ (production) ---
# Используем минимальный образ для продакшена
FROM python:3.9-slim
# Устанавливаем рабочую директорию
WORKDIR /app
# Копируем установленные пакеты из этапа 'builder'
# /root/.local/lib/python3.9/site-packages - стандартный путь для --user установки в slim-образах
COPY --from=builder /root/.local /root/.local
# Копируем исходный код приложения
COPY . .
# Добавляем пользовательскую директорию с пакетами в PATH
# Это необходимо, чтобы Python мог найти установленные зависимости
ENV PATH="/root/.local/bin:$PATH"
# Команда для запуска приложения
CMD ["python", "app.py"]
Пояснения к примеру:
FROM python:3.9-slim as builder: Первый этап, названныйbuilder, используетpython:3.9-slimдля установки зависимостей.RUN pip install --user -r requirements.txt: Зависимости устанавливаются в пользовательскую директорию (/root/.local), чтобы их было легко изолировать и скопировать.FROM python:3.9-slim: Второй этап начинается с чистогоpython:3.9-slimобраза, который будет финальным.COPY --from=builder /root/.local /root/.local: Копируем только установленные зависимости изbuilderэтапа в финальный образ.ENV PATH="/root/.local/bin:$PATH": Обновляем переменную окруженияPATH, чтобы исполняемые файлы из установленных пакетов были доступны.
Этот подход значительно уменьшает размер итогового образа, так как он не содержит pip и других инструментов, использованных только на этапе сборки.