Ответ
Multi-stage builds — это функция Docker, позволяющая использовать несколько инструкций FROM в одном Dockerfile. Каждая FROM-инструкция начинает новый этап сборки. Это позволяет отделить этап сборки приложения от этапа создания итогового образа, что значительно уменьшает его размер и повышает безопасность.
Как это работает:
- Этап сборки (builder): Используется образ со всеми компиляторами и инструментами сборки (Maven, Gradle, GCC). Здесь происходит компиляция и сборка артефакта.
- Финальный этап (runtime): Используется минимальный runtime-образ (например, JRE, а не JDK, или
alpine). Из предыдущего этапа копируется только готовый артефакт (JAR-файл, бинарник).
Пример для Spring Boot приложения:
# --- ЭТАП 1: Сборка ---
# Используем образ с Maven и JDK для компиляции
FROM maven:3.8.6-eclipse-temurin-17 AS builder
WORKDIR /app
# Копируем файлы с зависимостями для кэширования
COPY pom.xml .
RUN mvn dependency:go-offline -B
# Копируем исходный код и собираем приложение
COPY src ./src
RUN mvn clean package -DskipTests
# --- ЭТАП 2: Запуск ---
# Используем минимальный образ только с JRE
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# Копируем JAR-файл из этапа сборки, а НЕ исходники и Maven
COPY --from=builder /app/target/*.jar app.jar
# Открываем порт и задаем команду запуска
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
Преимущества:
- Меньший размер образа: Финальный образ не содержит инструментов сборки, исходного кода и промежуточных файлов. Разница может составлять сотни мегабайт.
- Повышенная безопасность: Сокращается поверхность атаки, так как в продакшн-образе меньше пакетов и уязвимостей.
- Четкое разделение: Упрощает
Dockerfileи делает процесс сборки более прозрачным. - Эффективное использование кэша: Этапы кэшируются независимо, что ускоряет повторные сборки.