Как Docker понимает, что нужно сбросить кэш при сборке образа?

«Как Docker понимает, что нужно сбросить кэш при сборке образа?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Основные триггеры сброса кэша:

  1. Изменение инструкции в Dockerfile: Если изменится любая инструкция, все последующие шаги будут пересобраны. Например, изменение RUN apt-get update приведет к пересборке всех следующих за ним RUN, COPY и т.д.
  2. Изменение содержимого файлов, копируемых командой COPY или ADD: Docker вычисляет контрольную сумму (хеш) для каждого копируемого файла. Если хеш изменился (файл был модифицирован), кэш сбрасывается на этом шаге и далее.
  3. Изменение базового образа (FROM): Если обновился образ в FROM alpine:latest, сборка начнется заново.

Пример для понимания:

# Шаг 1: Редко меняется, кэшируется хорошо
FROM node:18-alpine
# Шаг 2: Кэш сбросится, если изменится package.json или package-lock.json
COPY package*.json ./ 
# Шаг 3: Кэш сбросится, если сбросился предыдущий шаг
RUN npm ci --only=production
# Шаг 4: Кэш сбросится при изменении ЛЮБОГО файла в исходном коде
COPY src/ ./src

Принудительный сброс: Для полной пересборки без кэша используется флаг --no-cache:

docker build --no-cache -t myapp:latest .

В CI/CD-пайплайнах мы стратегически упорядочиваем инструкции в Dockerfile, чтобы редко меняющиеся зависимости кэшировались, а сборка была максимально быстрой.