Ускорение сборки Docker с помощью кэша сборки

Источник: «How to Speed Up Docker Builds with Build Cache»
Как хранить и совместно использовать кэш сборок Docker в разных командах с помощью реестра Docker.

Введение

Сейчас Docker является основным инструментом для создания, доставки и запуска контейнерных приложений. Одной из проблем, с которой может столкнуться разработчик, это время сборки, особенно для больших и сложных кодовых баз.

Кэш сборки Docker может предложить мощное решение этой проблемы, позволяя повторно использовать ранее созданные слои.

В статье мы рассмотрим, как создавать и хранить кэш сборки для различных этапов, например для этапа сборки, и как делиться этим кэшем с командой с помощью Docker Registry.

Понимание кэша сборки Docker

Кэш сборки Docker — механизм, позволяющий Docker повторно использовать слои из предыдущих сборок. Каждая инструкция в Dockerfile создаёт новый слой, и Docker кэширует эти слои, чтобы избежать лишней работы. Когда вы пересобираете образ, Docker проверяет, может ли он повторно использовать какие-либо из кэшированных слоёв, что позволяет значительно сократить время сборки.

Многоэтапные сборки и кэширование

Многоэтапные сборки — мощная функция в Docker, позволяющая использовать несколько операторов FROM в Dockerfile. Это позволяет создавать промежуточные этапы, такие как этап сборки, которые можно кэшировать и использовать повторно независимо друг от друга. Кэширование этих этапов позволяет дополнительно оптимизировать процесс сборки.

Настройка кэша сборки Docker

Шаг 1: Создание многоэтапного Dockerfile

Сначала создайте Dockerfile с несколькими этапами. Вот пример:

# Stage 1: Builder
FROM node:14 AS builder
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Production
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html

Шаг 2: Немного настроек

На локальном уровне, возможно, придётся использовать containerd, чтобы воспользоваться функцией кэширования.

В настройках Docker Desktop на вкладке General необходимо включить опцию Use containerd for pulling and storing images.

Опция \`Use containerd for pulling and storing images\` в Docker Desktop
Опция "Use containerd for pulling and storing images" в Docker Desktop

Также рекомендую добавить переменную среды: DOCKER_BUILDKIT=1

Шаг 3: Сборка первого этапа и выгрузка кэша

Чтобы собрать образ и выгрузить кэш в Docker Registry, выполните следующие команды:

docker build --target builder \
--cache-to=type=registry,ref=myregistry.com/myapp:cache-builder \
-t myapp:builder-latest .

Итак, вы создали, но не выгрузили, всё равно что-то было записано в наш реестр. Слои кэша были записаны в ваш реестр.

Можно немного подправить параметры кэша, и сжать слои, чтобы они занимали меньше места при хранении: compression=zstd,mode=max

docker build --target builder \
--cache-to=type=registry,ref=myregistry.com/myapp:cache-builder,compression=zstd,mode=max \
-t myapp:builder-latest .

Шаг 4: Сборка второго этапа с использованием кэша сборки

docker build --cache-from=type=registry,ref=myregistry.com/myapp:cache-builder -t myapp:latest .

# Выгружаем финальный образ
docker push myregistry.com/myapp:latest

Также можно использовать -cache-from и -cache-to с Github Actions: build-push-action

Шаг 5: Обновление docker-compose

Чтобы ваша команда могла воспользоваться данным кэшем, если она использует docker-compose, необходимо просто добавить его в сборку:

version: '3.5'

services:
myapp:
build:
context: .
args:
- DOCKER_BUILDKIT=1
cache_from:
- type=registry,ref=myregistry.com/myapp:cache-builder
...

Совместное использование кэша сборки

Храня кэш сборки в реестре Docker, им можно поделиться с командой. Это гарантирует, что все будут пользоваться кэшированными слоями, сокращая время сборки и повышая производительность.

Лучшие практики использования кэша сборки Docker

  1. Используйте многоэтапные сборки: Разбейте свой Dockerfile на несколько этапов, это позволит оптимизировать кэширование.
  2. Минимизируйте изменения слоёв: Группируйте часто меняющиеся инструкции вместе, чтобы минимизировать инвалидацию кэша.
  3. Используйте .dockerignore: Исключите ненужные файлы из контекста сборки, для ускорения процесса сборки.
  4. Регулярно обновляйте кэш: Периодически перестраивайте и обновляйте кэш, чтобы он оставался актуальным с учётом последних изменений.

Заключение

Использование кэша сборки Docker может значительно улучшить рабочий процесс разработки, сократив время сборки и сделав процесс более эффективным. Благодаря хранению и совместному использованию кэша в реестре Docker можно гарантировать, что все члены команды получат выгоду от этой оптимизации. Внедрение этих практик приведёт к ускорению сборки, повышению производительности и более плавному процессу разработки.

Комментарии


Дополнительные материалы

Предыдущая Статья

Защитите Node.js приложения с `npx is-my-node-vulnerable`

Следующая Статья

Три подхода к селектору & (амперсанд) в CSS