Docker собирает образ слоями и старается переиспользовать кеш. Если слой не изменился, он берётся из кеша, а следующая команда не выполняется заново.
Проблема часто появляется в Node, Python, Java и других проектах, где зависимости устанавливаются до копирования всего исходного кода.
Неудачный Dockerfile может выглядеть так:
COPY . .
RUN npm ci
RUN npm run build
Теперь любое изменение в одном файле проекта сбивает кеш для COPY . . После этого npm ci запускается заново, даже если package.json вообще не менялся.
Лучше сначала копировать только файлы зависимостей:
COPY package*.json ./
RUN npm ci
Этот слой будет пересобираться только тогда, когда реально изменились зависимости. Правки в исходниках больше не заставят Docker каждый раз скачивать и устанавливать пакеты.
Исходный код копируют уже после установки:
COPY . .
RUN npm run build
Такая же идея работает и для других стеков. В Python сначала копируют requirements.txt или pyproject.toml, в Java отдельно копируют pom.xml или gradle-файлы.
Например для Maven:
COPY pom.xml ./
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package
Редко меняющиеся файлы ставим выше, часто меняющийся код ниже. Тогда кеш Docker начинает реально помогать, а сборки в CI идут заметно быстрее.
➡️ DevOps Ready | #совет
