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

Быстрые ссылки
- Как работает кэш
- Отключение кэша
- Загрузка обновлённых базовых образов
- Использование Docker Compose
- Очистка кэша сборки
- Краткое руководство и чек-листы
Как работает кэш
Docker ускоряет повторные сборки, повторно используя промежуточные слои образа. Каждый шаг Dockerfile (инструкция) создаёт слой. Если контекст и инструкция не изменились, Docker может взять слой из кэша, а не повторно выполнять шаг.
Короткое определение терминов:
- Слой: результат выполнения одной инструкции Dockerfile.
- Кэш: набор ранее созданных слоёв, хранящихся локально.
Рассмотрим простой Dockerfile:
FROM alpine:latest
COPY 1.txt /1.txt
COPY 2.txt /2.txtПодготовьте файлы и соберите образ:
$ echo 1 > 1.txt$ echo 2 > 2.txt$ docker build -t demo:latest .Вывод будет похож на следующий:
Sending build context to Docker daemon 5.12kB
Step 1/3 : FROM alpine:latest
---> 9c6f07244728
Step 2/3 : COPY 1.txt /1.txt
---> db61ff73c0b5
Step 3/3 : COPY 2.txt /2.txt
---> f1129e47fc12
Successfully built f1129e47fc12
Successfully tagged demo:latestТеперь измените 2.txt и повторно выполните сборку:
$ echo two > 2.txt$ docker build -t demo:latest .Sending build context to Docker daemon 5.12kB
Step 1/3 : FROM alpine:latest
---> 9c6f07244728
Step 2/3 : COPY 1.txt /1.txt
---> Using cache
---> db61ff73c0b5
Step 3/3 : COPY 2.txt /2.txt
---> 75ba7d786049
Successfully built 75ba7d786049
Successfully tagged demo:latestВо втором проходе видно “Using cache” для шага с 1.txt, потому что его содержимое не изменилось. Промежуточный слой с идентификатором db61ff73c0b5 переиспользуется.
Отключение кэша
Чтобы запрещать Docker использовать промежуточный кэш слоёв, передавайте флаг --no-cache:
$ echo second > 2.txt$ docker build --no-cache -t demo:latest .Sending build context to Docker daemon 5.12kB
Step 1/3 : FROM alpine:latest
---> 9c6f07244728
Step 2/3 : COPY 1.txt /1.txt
---> 1590b2407dd4
Step 3/3 : COPY 2.txt /2.txt
---> afb31630ce32
Successfully built afb31630ce32
Successfully tagged demo:latestЗдесь даже шаг с 1.txt пересобран и создал новый слой 1590b2407dd4. Используйте --no-cache, когда подозреваете, что кэш устарел, либо хотите имитировать сборку на чистой машине. Учтите, что полная сборка без кэша будет медленнее.
Важно: --no-cache заставляет Docker не использовать локальный набор промежуточных слоёв при построении, но не обновляет базовые образы автоматически.
Загрузка обновлённых базовых образов
Отдельный вид кэширования — это локально сохранённые базовые образы (упомянутые в FROM). Docker по умолчанию не подтягивает свежую версию тега образа, если он уже есть на хосте. Это может привести к тому, что на двух разных машинах результат сборки будет отличаться, если на одной из них локальный базовый образ устарел.
Чтобы явно проверить регистри и скачать свежий базовый образ, используйте флаг --pull при сборке. Он извлечёт манифест тега из реестра и сравнит с локальной версией. При расхождении — образ будет загружен.
$ docker build --no-cache --pull -t demo:latest .Sending build context to Docker daemon 5.12kB
Step 1/3 : FROM alpine:latest
latest: Pulling from library/alpine
Digest: sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad
Status: Image is up to date for alpine:latest
---> 9c6f07244728
Step 2/3 : COPY 1.txt /1.txt
---> 4fee970dfaab
Step 3/3 : COPY 2.txt /2.txt
---> 60d2e3fff0fb
Successfully built 60d2e3fff0fb
Successfully tagged demo:latestЕсли образ уже совпадает по манифесту, Docker сообщит, что образ актуален. --pull и --no-cache независимы: --pull обновляет базовые образы, --no-cache отключает промежуточный кэш.
Совет: в CI-пайплайнах используйте --pull для воспроизводимости между сборками на разных хостах.
Использование Docker Compose
Docker Compose поддерживает аналогичные флаги для команды build. В Compose v2 и v1 синтаксис немного отличается по названию команды, но флаги те же.
# Compose v2$ docker compose build --no-cache --pull# Compose v1$ docker-compose build --no-cache --pullЕсли в docker-compose.yml указан секция build с контекстом и аргументами, Compose передаст флаги в движок сборки и применит те же правила, что и docker build.
Очистка кэша сборки
Чтобы гарантировать, что локальный кэш не используется и освободить дисковое пространство, примените команду очистки билдера:
$ docker builder pruneПо умолчанию команда удаляет «висячие» кэши, связанные с образами, которые больше не присутствуют локально. Чтобы удалить весь кэш, включая слои, используемые существующими образами, добавьте флаг -a:
$ docker builder prune -aКоманда принимает опцию --filter, чтобы удалять кеши по времени или другим критериям:
# Удалить кеши, изменённые за последние 2 часа$ docker builder prune --filter since=2h# Удалить кеши, изменённые более двух часов назад$ docker builder prune --filter until=2hВажно: docker builder prune действует на кеш BuildKit. Если вы используете старый режим сборки (не BuildKit), поведение отличается.
Когда чистая сборка не решит проблему
- Если баг вызван в рантайме (например, несовместимость библиотек при запуске), пересборка образа не решит проблему.
- Если наслоение версий зависимостей (внутри пакетов) скрыто внутри кэша менеджеров пакетов — нужно очищать кеши этих менеджеров (npm, pip, apt) в Dockerfile.
- Если проблема в некорректном Dockerfile (неоптимальные инструкции, ORDER), простая пересборка не исправит логику.
Альтернативные подходы
- Создать минимальный чистый CI-агент или VM и выполнить сборку там — гарантирует чистую среду без локальных артефактов.
- Использовать immutable tags (фиксированные теги образов, например alpine:3.18) вместо latest — повышает воспроизводимость.
- Явно очищать кеши менеджеров пакетов в Dockerfile (apt-get clean, npm ci) для детерминированных слоёв.
Минимальная методология для воспроизводимой сборки
- Зафиксируйте версии базовых образов (используйте конкретные теги или SHA).
- В CI установите docker build –pull для синхронизации базовых образов.
- При отладке сборки используйте –no-cache, чтобы исключить влияние локального кэша.
- Периодически выполняйте docker builder prune -a на билд-серверах по расписанию.
Чек-листы по ролям
Разработчик:
- Использовать –no-cache локально при подозрении на кэш-проблему.
- Проверять содержимое COPY/ADD и аргументы build ARG, которые влияют на кэш.
- Фиксировать теги базовых образов при необходимости.
Инженер CI/CD:
- Добавить –pull в этап сборки CI.
- Планировать регулярную очистку кэша билдера на билдерах.
- Логировать манифесты образов (digest) для отладочных записей.
Оператор инфраструктуры:
- Мониторить использование диска Docker (docker system df).
- Запланировать очистку кеша и старых образов.
- Обеспечить резервное копирование образов, если необходимо.
Быстрая шпаргалка команд
- Сборка без кэша: docker build –no-cache -t myimage:tag .
- Сборка с проверкой базовых образов: docker build –pull -t myimage:tag .
- Комбинация: docker build –no-cache –pull -t myimage:tag .
- Compose: docker compose build –no-cache –pull
- Очистка висячего кэша: docker builder prune
- Очистка всего кэша: docker builder prune -a
- Фильтрация очистки: docker builder prune –filter since=24h
Критерии приёмки
- При сборке с –no-cache все промeжуточные слои пересоздаются.
- При добавлении –pull базовый образ обновился или Docker явно сообщил, что образ актуален.
- Логи сборки содержат идентификаторы новых слоёв, а не “Using cache” для релевантных шагов.
Отладка: типичные ошибки и как их найти
- “Using cache” появляется, хотя вы меняли файлы: проверьте, что вы изменили тот файл, который действительно копируется в шаге, и что контекст сборки корректен.
- Образ не обновляется после –pull: убедитесь, что используемый тег действительно имеет новый манифест в реестре (может понадобиться docker pull
). - Проблемы с пространством диска: выполните docker system df и затем docker builder prune -a.
Ментальные модели и эвристики
- Модель: представьте каждый шаг Dockerfile как «моментальную фотографию» состояния FS. Если входные данные не изменились, фотографию можно reuse.
- Эвристика: если сборка ведёт себя по-разному на двух хостах — сначала проверьте базовые образы (
--pull), затем кэш слоёв (--no-cache).
Пример CI-фрагмента (сборка в GitHub Actions)
- name: Build Docker image
run: docker build --pull --no-cache -t myorg/myapp:${{ github.sha }} .Маленькая галерея крайних случаев
- Локальный образ с тем же тегом, но отличным содержимым в реестре:
--pullрешит ситуацию. - Кэш менеджера пакетов внутри слоя: добавьте очистку кеша менеджера в Dockerfile.
- Неоднозначность контекста (копирование из пути вне контекста): Docker не увидит изменения и может использовать старое поведение.
Краткое руководство по выбору флагов
- Локальная быстрая сборка для разработки: без флагов или с кэшем.
- Отладка проблем воспроизводимости: –no-cache (локально) + –pull (для синхронизации баз).
- CI-потоки, где важна детерминированность: всегда –pull; периодически –no-cache для проверки.
Сводка
Кэш сборки Docker ускоряет работу, но может скрывать изменения и создавать разные результаты на разных хостах. Флаги --no-cache и --pull позволяют получить чистую сборку: --no-cache отключает использование промежуточных слоёв, --pull обновляет базовые образы из реестра. Команда docker builder prune помогает очистить локальный кэш и освободить место. Включите эти практики в CI и процессы обслуживания билд-серверов, чтобы повысить воспроизводимость и предсказуемость сборок.
Ключевые действия: использовать –pull в CI, применять –no-cache для отладки, планировать периодическую очистку кеша сборки.
Похожие материалы
PUBG падает в Windows 11 — как исправить
Исправить ошибку «Oops! Something went wrong» в YouTube
Экран входа macOS — настройки и советы
Удалить историю Google Bard и отключить её
TinyLetter для блогеров: быстро и просто