Ответ
Docker использует механизм кэширования слоев для ускорения сборки образов. Кэш сбрасывается (инвалидируется) на определенном шаге, когда Docker обнаруживает изменение, которое делает предыдущий кэшированный слой невалидным.
Основные триггеры сброса кэша:
- Изменение инструкции в Dockerfile: Если изменится любая инструкция, все последующие шаги будут пересобраны. Например, изменение
RUN apt-get updateприведет к пересборке всех следующих за нимRUN,COPYи т.д. - Изменение содержимого файлов, копируемых командой
COPYилиADD: Docker вычисляет контрольную сумму (хеш) для каждого копируемого файла. Если хеш изменился (файл был модифицирован), кэш сбрасывается на этом шаге и далее. - Изменение базового образа (
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, чтобы редко меняющиеся зависимости кэшировались, а сборка была максимально быстрой.