Что такое многоэтапные сборки (multi-stage builds)?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Многоэтапные сборки в Docker позволяют разделить процесс сборки и итоговый runtime-образ. Сначала в одном этапе ставятся зависимости и собирается артефакт, а потом в финальный образ попадает только то, что нужно для запуска. Это уменьшает размер образа, повышает безопасность и упрощает доставку.
Определение:
Multi-stage builds — это способ писать Dockerfile с несколькими FROM, где каждый этап выполняет свою задачу. Обычно первый этап используется для сборки приложения, а последний — для создания компактного образа для запуска. Между этапами можно копировать только нужные файлы, не таща в финальный образ инструменты сборки и лишние зависимости.
Пример использования:
Например, для Ruby-приложения можно в первом этапе установить gems и подготовить приложение, а во втором оставить только runtime-зависимости и код приложения.
# Stage 1: build
FROM ruby:3.3 AS builder
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
RUN bundle exec rake assets:precompile
# Stage 2: runtime
FROM ruby:3.3-slim
WORKDIR /app
COPY --from=builder /app /app
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
Пояснение кода:
Код нужен, потому что здесь речь про Dockerfile.
FROM ruby:3.3 AS builder— задаёт первый этап, в котором есть всё необходимое для сборки.WORKDIR /app— устанавливает рабочую директорию.COPY Gemfile Gemfile.lock ./иRUN bundle install— устанавливают зависимости только на этапе сборки.COPY . .— копирует исходники приложения.RUN bundle exec rake assets:precompile— выполняет тяжёлую сборочную операцию, результат которой нужен в финальном образе.FROM ruby:3.3-slim— начинается второй этап, более лёгкий и предназначенный для запуска.COPY --from=builder /app /app— переносит из builder-стадии только нужные файлы.CMD [...]— задаёт команду запуска приложения.
Ключевые моменты:
- Финальный образ не содержит build-инструментов, если они не нужны для запуска.
- Размер образа обычно заметно меньше.
- Снижается поверхность атаки за счёт удаления лишних пакетов и утилит.
- Можно отдельно оптимизировать этап сборки и этап запуска.
- Удобно для языков и фреймворков, где есть сборка артефактов перед запуском.
- В Dockerfile можно использовать несколько этапов и копировать из одного этапа в другой только нужные файлы.