middle
Что такое multi-stage build и зачем он нужен?
Multi-stage build (многоступенчатая сборка) — это подход, при котором в одном Dockerfile используется несколько инструкций FROM, где каждая начинает новую стадию сборки, а в финальный образ попадает только результат последней стадии.
Зачем нужен
- Разделение среды сборки и среды выполнения
- Уменьшение размера финального образа — в него не попадают инструменты сборки (Maven, Gradle, JDK)
- Один Dockerfile для всего процесса — от исходного кода до готового образа
Пример для Spring Boot приложения с Maven
Пример
# --- Стадия 1: сборка ---
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
# Загружаем зависимости отдельным слоем (кэширование)
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests -B
# --- Стадия 2: запуск ---
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# Копируем только JAR из стадии сборки
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Результат: финальный образ содержит только JRE и JAR-файл, без Maven, JDK, исходного кода и промежуточных артефактов. Размер образа может уменьшиться с ~800 МБ до ~200 МБ.
Пример с Gradle
FROM gradle:8.5-jdk17 AS build
WORKDIR /app
COPY build.gradle settings.gradle ./
COPY src ./src
RUN gradle bootJar --no-daemon
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
На собеседовании: объясните главную идею: multi-stage build позволяет собирать приложение в одном контейнере (с JDK и Maven), а запускать в другом (только JRE). Это уменьшает размер образа и поверхность атаки. Покажите, что знаете синтаксис
COPY --from=build.