Sobes.tech
Назад к вопросам
Middle
541
questionbank

Что такое многоэтапные сборки (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.

  1. FROM ruby:3.3 AS builder — задаёт первый этап, в котором есть всё необходимое для сборки.
  2. WORKDIR /app — устанавливает рабочую директорию.
  3. COPY Gemfile Gemfile.lock ./ и RUN bundle install — устанавливают зависимости только на этапе сборки.
  4. COPY . . — копирует исходники приложения.
  5. RUN bundle exec rake assets:precompile — выполняет тяжёлую сборочную операцию, результат которой нужен в финальном образе.
  6. FROM ruby:3.3-slim — начинается второй этап, более лёгкий и предназначенный для запуска.
  7. COPY --from=builder /app /app — переносит из builder-стадии только нужные файлы.
  8. CMD [...] — задаёт команду запуска приложения.

Ключевые моменты:

  • Финальный образ не содержит build-инструментов, если они не нужны для запуска.
  • Размер образа обычно заметно меньше.
  • Снижается поверхность атаки за счёт удаления лишних пакетов и утилит.
  • Можно отдельно оптимизировать этап сборки и этап запуска.
  • Удобно для языков и фреймворков, где есть сборка артефактов перед запуском.
  • В Dockerfile можно использовать несколько этапов и копировать из одного этапа в другой только нужные файлы.