Очистить кэш компоновки Docker

Обновлено: 28.06.2024

В этом документе показано, как использовать Layer Caching в Docker для ускорения сборки и как применять его в рабочих процессах CI/CD на Semaphore.

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

Docker использует кеш слоев для оптимизации и ускорения процесса создания образов Docker.

Кэширование Docker Layer в основном работает с командами RUN , COPY и ADD, которые будут объяснены более подробно далее.

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

Как вы увидите позже, команда COPY или ADD может сделать кэш слоя недействительным и заставить Docker выполнять все команды RUN.

Команда COPY в файле Docker позволяет импортировать один или несколько внешних файлов в образ Docker. При выполнении команды COPY гарантируют наличие последней версии всех соответствующих внешних файлов.

Если содержимое всех внешних файлов в первой команде COPY одинаково, будет использоваться кэш слоя, а все последующие команды до следующей команды ADD или COPY будут использовать кэш слоя.

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

Чтобы воспользоваться преимуществами Layer Caching в Docker, вы должны структурировать свой Dockerfile таким образом, чтобы часто изменяющиеся шаги, такие как COPY, располагались ближе к концу файла Dockerfile. Это гарантирует, что шаги, связанные с выполнением одного и того же действия, не будут перестроены без необходимости.

Команда ADD в файле Docker позволяет импортировать внешние файлы в образ Docker.

Если содержимое всех внешних файлов в первой команде ADD одинаково, будет использоваться кэш слоя, а все последующие команды до следующей команды ADD или COPY будут использовать кэш слоя.

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

Чтобы воспользоваться преимуществами Layer Caching в Docker, вы должны структурировать свой Dockerfile таким образом, чтобы часто изменяющиеся шаги, такие как ADD, располагались ближе к концу файла Dockerfile. Это гарантирует, что шаги, связанные с выполнением одного и того же действия, не будут перестроены без необходимости.

Параметр командной строки --cache-from в команде docker позволяет создать новый образ, используя уже существующий в качестве источника кэша. Вы увидите это более подробно в следующем разделе.

Первое, что вам нужно, это создать секрет данных реестра Docker в Semaphore 2.0. Назовем его docker-hub, а узнать о нем больше информации можно следующим образом:

Следующее иллюстрирует использование кэширования Docker Layer в проектах Semaphore 2.0:

Файл .semaphore/semaphore.yml состоит из двух блоков. Первый создает образ Docker, который повторно используется во втором блоке блоков с помощью параметра командной строки --cache-from.

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

Команда docker pull получает существующий образ Docker из реестра Docker, тогда как команда docker build использует параметр --cache-from, чтобы попытаться повторно использовать как можно больше существующих слоев $DOCKER_USERNAME:go_hw:$ изображение SEMAPHORE_GIT_BRANCH.

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

Последние две команды docker следует выполнять, если вы хотите развернуть образ Docker в рабочей среде. Первый помечает существующий образ Docker таким образом, чтобы его можно было связать со значением Git SHA и идентификатором рабочего процесса проекта Semaphore 2.0, а второй отправляет этот образ в реестр Docker.

Содержимое файла D1 следующее:

Содержимое файла D2 следующее:

Файл D2 включает в себя все содержимое файла D1 и добавляет еще одну строку в конце, что делает его идеальным кандидатом на использование образа Docker, созданного с использованием D1 в качестве кеша.

Чтобы обеспечить лучшее попадание в кеш, в качестве тега следует выбрать переменную среды SEMAPHORE_GIT_BRANCH Semaphore 2.0. Таким образом, у каждой ветки GitHub будет свой кеш, и вы избежите конфликта кеша.

Текст был успешно обновлен, но возникли следующие ошибки:

прокомментировал pascalandy 20 апреля 2016 г.

Я искал это!!

Вот мой чистый способ перестроить мой стек композиций

cd (к вашему каталогу создания)

Разумно? Я ищу здесь лучшие практики :)

lucj прокомментировал 27 апреля 2016 г.

+1
Нужен ли параметр --force-recreate?

прокомментировал pozgo 4 августа 2016 г.

+1
Я думаю, что --force-recreate — лучший выбор

комментарий aanand от 4 августа 2016 г.

--force-recreate не нужен, так как все контейнеры только что были удалены.

Если вы хотите очистить все, down лучше, чем rm , поскольку он также может удалять тома и сети.

прокомментировал pascalandy 4 августа 2016 г. •

Я использую его уже 3 месяца, и он идеально подходит для моих нужд.
Я не хочу удалять: сети, тома и изображения

Я буду рад использовать что-то короче или чище. У меня все в порядке :)

прокомментировал julianfrank 25 октября 2016 г.

--no-cache не работает. какова альтернатива --force-rebuild продолжает использовать кеш :(

maciej-gurban прокомментировал 28 ноября 2016 г.

@julianfrank Не уверен, что вы имели в виду под --no-cache, не работает, но, возможно, вы запускаете его как
docker-compose build SERVICE_NAME --no-cache
, когда на самом деле это должен быть docker -compose build --no-cache SERVICE_NAME ?

прокомментировал julianfrank 8 января 2017 г.

Если шаги для разных создаваемых служб одинаковы, он по-прежнему использует кеш из контейнера, только что созданного ранее в сценарии. Разработал альтернативу для использования тех же шагов, когда я хочу использовать кеш, и изменить порядок, чтобы принудительно пропустить использование кеша.

gpgpublickey прокомментировал 25 января 2019 г. •

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

ivanleoncz прокомментировал 25 апреля 2019 г. •

Действительно, это не работает.
Вы можете вносить все изменения в Dockerfile для службы, и это не влияет на сборку docker-compose --no-cache

комментарий mo18 прокомментирован 20 мая 2019 г.

docker-compose up -d --build --no-deps web перестроит контейнер для службы с именем "web" в файле docker-compose.yml. После завершения перестроения указанный контейнер будет перезапущен.

--no-deps ограничит перестроение именем службы, указанным в команде.

Кроме того, эта команда перестроит контейнер, если вы копируете файлы в контейнер, а один из файлов, которые вы копируете, изменился, например, требования.txt

SimonGitter прокомментировал 5 декабря 2019 г. •

К вашему сведению
docker-compose up --force-recreate --build

Очевидно, что для команды up нет параметра --no-cache
Похоже, что принудительное воссоздание не использует этот параметр. Пожалуйста, поправьте меня, если я ошибаюсь!

Поэтому лучше всего сделать это мне.

Идеальная команда компоновки для меня

Удаляет контейнер и образы > создает образы без кеша сборки > docker-compose up detached > следит за журналами (чтобы вы могли выйти из него с помощью Ctrl+C)

docker-compose build --force-rm --no-cache && docker-compose up --detach && docker-compose logs -f

Windows:
docker-compose build --force-rm --no-cache ; docker-compose up --detach ; журналы составления докеров -f

Когда вы выполняете команду Docker pull или Docker run, демон сначала проверяет наличие похожего образа на локальном компьютере, сравнивая дайджесты образа.

Если он находит совпадение, то поиск образа в реестре не требуется, и демон может просто создать копию уже существующего образа. Однако, если копия не найдена, начинает извлекать ее из реестра. То же самое происходит, когда вы пытаетесь создать образ с помощью Dockerfile.

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

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

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

Рассмотрите Dockerfile ниже.

В приведенном выше Dockerfile мы использовали две разные инструкции RUN в отдельных строках. Это приводит к созданию отдельных слоев изображений и построению кэшей.Когда демон Docker обрабатывает команду обновления, такую ​​как RUN apt-get -y update, те пакеты внутри контейнера, над которыми работают команды обновления, не сравниваются, чтобы определить, произошло ли попадание в кэш или нет. В таком случае для поиска соответствия сравнивается только командная строка.

Вместо того, чтобы использовать две отдельные строки для двух последовательных инструкций RUN, вы можете объединить их, чтобы уменьшить количество слоев изображения и, следовательно, уменьшить вероятность попадания в кэш.

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

Например, если вы хотите создать образ из следующего Dockerfile —

Предположим, вы уже построили этот образ ранее, а теперь внесли некоторые изменения в контекст сборки. Следовательно, кэш инструкции COPY разрывается, как и кэш всех последующих инструкций. Если вы не внесли никаких изменений и создали образ заново, разрыва кеша не происходит, и демон просто использует существующий кеш слоев изображения для построения образа.

Это поведение по умолчанию, и если вы хотите переопределить это поведение по умолчанию, вы можете использовать параметр --no-cache вместе с командой сборки Docker.

При выполнении этой команды демон не будет искать кешированные сборки существующих слоев образа и принудительно создаст чистую сборку образа Docker из Dockerfile.

Если вы используете Docker compose, вы можете использовать следующую команду.

Вы также можете связать это с командой up, чтобы воссоздать все контейнеры.

Обратите внимание, что в этих способах не используется кеш, а ссылка на построитель и базовые образы осуществляется с помощью инструкции FROM. Вы можете очистить кеш билдера, используя -

Вы также можете очистить родительские изображения, если не хотите использовать их кеш.

Это наиболее распространенные подходы, которые можно использовать для принудительной очистки сборки образа и предотвращения использования кэшей слоев изображения. Лучший и, возможно, самый простой вариант — использовать параметр --no-cache.

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

  1. Убедитесь, что все контейнеры закрыты или уничтожены.
  2. Удалите все локально созданные образы. Для стандартного развертывания docker-compose это означает xnat-web, xnat-db и xnat-orthanc. Вы можете проверить список локальных изображений, чтобы убедиться, что локально хранятся только загруженные изображения.
  3. Удалите все неиспользуемые тома Docker.
  4. Удалите все папки данных *-data. Эти папки содержат, среди прочего, базу данных XNAT, архивные папки, загруженные jar-файлы war и plugin и т. д.
  5. Удалите все папки версий для войны XNAT и подключаемых модулей в локальном кеше Maven и Gradle.

Для первого шага вы должны сначала закрыть все запущенные конфигурации docker-compose:

Вы можете использовать следующую команду, чтобы убедиться, что ничего не запущено:

Флаг --all включает контейнеры, которые были запущены, но по какой-то причине остановлены. Если у вас все еще работают отдельные контейнеры, используйте следующую команду, чтобы убить их:

Чтобы удалить образы локальной сборки, сначала перечислите все образы, кэшированные локально, а затем удалите все, что было создано локально:

Сокращение томов означает, что Docker удаляет все тома, на которые не ссылается запущенный в данный момент контейнер:

Данные также хранятся в различных папках *-data, созданных с помощью docker-compose. Вы можете удалить их примерно так:

Наконец, чтобы убедиться, что вы получаете последнюю «официальную» сборку войны XNAT и различных подключаемых модулей, вы можете очистить кэши локальных репозиториев Maven и Gradle, чтобы функция управления зависимостями загрузила эти артефакты из XNAT Maven. репозиторий. Вы можете просто удалить все свои репозитории Maven и Gradle (за исключением некоторых вещей, таких как файлы settings.xml и gradle.properties), но тогда последующие сборки займут довольно много времени, пока не будут загружены кешированные элементы, такие как плагины и оболочки. опять таки. Вместо этого вы можете просто удалить папки, содержащие артефакты, указанные в вашем файле manifest.json. Например, на основе манифеста для XNAT-ML, показанного в инструкциях по установке Docker-Compose, вы можете запустить такой сценарий:

Все имена файлов основаны на идентификаторе артефакта и версии с подстановочным знаком (*) для учета возможных различий в именах в разрабатываемых или будущих сборках. Удаление папки, содержащей файл (выполненное с использованием имени каталога, а не непосредственно имени файла), гарантирует, что метаданные, связанные с файлом jar или war, также будут удалены.

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

XNAT — это проект с открытым исходным кодом, созданный NRG в Медицинской школе Вашингтонского университета | Главная страница NRG

Вклады на сайт документации XNAT предоставляются под лицензией Creative Commons Attribution 3.0 Unported License.

Майкл Герман

Автор: Майкл Херман. Последнее обновление: 8 октября 2021 г.

Поделиться этим руководством

В этой статье рассказывается, как ускорить сборку на основе Docker в CircleCI, GitLab CI и GitHub Actions с помощью кэширования на уровне Docker и BuildKit.

Содержание

Кэширование слоя Docker

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

Вы можете найти полный исходный код этого проекта в репозитории docker-ci-cache на GitHub.

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

Даже если вы внесете изменения в исходный код, сборка займет всего несколько секунд, так как зависимости не нужно будет загружать. Только последние два слоя должны быть перестроены, другими словами:

Чтобы не сделать кеш недействительным:

  1. Начните свой Dockerfile с команд, которые вряд ли изменятся
  2. Поместите команды, которые с большей вероятностью изменятся (например, COPY . . .), как можно позже
  3. Добавьте только необходимые файлы (используйте файл .dockerignore)

Комплект сборки

Если вы используете версию Docker >= 19.03, вы можете использовать BuildKit, средство создания образов контейнеров, вместо традиционной серверной части средства создания образов внутри ядра Docker. Без BuildKit, если образ не существует в вашем локальном реестре образов, вам нужно будет извлечь удаленные образы перед сборкой, чтобы воспользоваться преимуществами кэширования уровня Docker.

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

Чтобы включить BuildKit, установите для переменной среды DOCKER_BUILDKIT значение 1 . Затем, чтобы включить кэширование встроенного слоя, используйте аргумент сборки BUILDKIT_INLINE_CACHE.

Среда CI

Поскольку платформы CI предоставляют свежую среду для каждой сборки, вам потребуется использовать удаленный реестр образов в качестве источника кэша для кэширования слоев BuildKit.

Войдите в реестр образов (например, в Docker Hub, Elastic Container Registry (ECR) и Quay).

Стоит отметить, что и GitLab, и GitHub имеют свои собственные реестры для использования в ваших репозиториях (как общедоступных, так и частных) на своих платформах — GitLab Container Registry и GitHub Packages соответственно.

Используйте параметр --cache-from сборки Docker, чтобы использовать существующий образ в качестве источника кеша.

Давайте посмотрим, как это сделать в CircleCI, GitLab CI и GitHub Actions, используя как одноэтапные, так и многоэтапные сборки Docker с Docker Compose и без него. В каждом из примеров используется Docker Hub в качестве реестра образов с REGISTRY_USER и REGISTRY_PASS, установленными в качестве переменных в сборках CI для отправки и извлечения из реестра.

Одноэтапные сборки

Создать

Если вы используете Docker Compose, вы можете добавить параметр cache_from в файл компоновки, который сопоставляется с командой docker build --cache-from при запуске docker-compose build .

Чтобы воспользоваться преимуществами BuildKit, убедитесь, что вы используете версию Docker Compose >= 1.25.0. Чтобы включить BuildKit, установите для переменных среды DOCKER_BUILDKIT и COMPOSE_DOCKER_CLI_BUILD значение 1 . Затем снова, чтобы включить кэширование встроенного слоя, используйте аргумент сборки BUILDKIT_INLINE_CACHE.

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

При использовании шаблона многоэтапной сборки вам придется применять один и тот же рабочий процесс (сборка, затем отправка) для каждого промежуточного этапа, поскольку эти образы отбрасываются до того, как будет создан окончательный образ. Параметр --target можно использовать для сборки каждого этапа многоэтапной сборки отдельно.

Создать

Пример создания файла:

Заключение

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

Каждый этап, добавляемый к шагу сборки, требует новой сборки и отправки вместе с добавлением параметров --cache-from для каждого родительского этапа. Таким образом, каждый новый этап будет добавлять больше беспорядка, делая файл CI все более трудным для чтения. К счастью, BuildKit поддерживает многоэтапные сборки с кэшированием слоев Docker, созданным с использованием одного этапа. Просмотрите следующие статьи для получения дополнительной информации о таких расширенных шаблонах BuildKit:

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

Код можно найти в репозитории docker-ci-cache:

Майкл Герман

Майкл Герман

Майкл — инженер-программист и преподаватель, живет и работает в Денвере/Боулдере. Он является соучредителем/автором Real Python. Помимо разработки, ему нравится создавать финансовые модели, писать технические статьи, контент-маркетинг и преподавать.

Поделиться этим руководством

Поделиться этим руководством

Разработка через тестирование с использованием Django, Django REST Framework и Docker

В этом курсе вы узнаете, как настроить среду разработки с помощью Docker, чтобы создать и развернуть RESTful API на основе Python, Django и Django REST Framework.

Темы руководства

Содержание

Разработка через тестирование с использованием Django, Django REST Framework и Docker

В этом курсе вы узнаете, как настроить среду разработки с помощью Docker, чтобы создать и развернуть RESTful API на основе Python, Django и Django REST Framework.

Читайте также: