Как я могу предотвратить кеширование инструкции Dockerfile?

В моем Dockerfile я использую curl или ADD для загрузки последней версии архива, например:

FROM debian:jessie
...
RUN apt-get install -y curl
...
RUN curl -sL http://example.com/latest/archive.tar.gz --output archive.tar.gz
...
ADD http://example.com/latest/archive2.tar.gz
...

Оператор RUN, использующий curl или ADD, создает свой собственный слой изображения. Это будет использоваться в качестве кеша для будущих запусков docker build.

Вопрос: как отключить кеширование для этих инструкций?

Было бы здорово, если бы там работало что-то вроде инвалидации кеша. Например. используя HTTP ETags или запрашивая поле заголовка последнее изменение. Это даст возможность выполнить быструю проверку на основе заголовков HTTP, чтобы решить, можно ли использовать кэшированный слой или нет.

Я знаю, что могут помочь некоторые грязные уловки, например, вместо этого выполняя сценарий оболочки загрузки в операторе RUN. Его имя файла будет изменено до того, как docker build будет запущен нашей системой сборки. И я мог бы проводить HTTP-проверки внутри этого скрипта. Но тогда мне нужно где-то сохранить либо последний использованный ETag, либо последний измененный файл. Мне интересно, есть ли здесь еще какие-нибудь чистые и нативные функции Docker, которые я мог бы использовать.


person 0x7d7b    schedule 03.08.2015    source источник


Ответы (3)


Можно указать аргумент времени сборки, чтобы принудительно сломать кеш, начиная с этого шага. Например, в вашем Dockerfile поместите

ARG CACHE_DATE=not_a_date

а затем присваивайте этому аргументу новое значение при каждой новой сборке. Лучшее, конечно же, - это временная метка.

docker build --build-arg CACHE_DATE=$(date +%Y-%m-%d:%H:%M:%S) ...

Убедитесь, что значение является строкой без пробелов, иначе докер-клиент ошибочно примет его как несколько аргументов.

См. Подробное обсуждение проблемы 22832.

person Ruifeng Ma    schedule 08.07.2016
comment
Или еще лучше накормить его $ RANDOM? - person d33tah; 10.07.2018
comment
С отметкой времени мы можем быть на 100% уверены, что значение всегда будет уникальным, кроме того, информация о временной отметке может быть полезна, если она будет использоваться где-то в контейнере. - person Ruifeng Ma; 18.07.2018
comment
Не следил за новыми выпусками Docker. Но идея, лежащая в основе этого решения, состоит в том, чтобы попытаться предоставить новое значение для разрушения кеша при каждом запуске сборки, что может быть реализовано множеством способов. Пока механизм кеширования Docker не меняется, можно найти аналогичный способ. - person Ruifeng Ma; 28.12.2018
comment
Приличный генератор случайных чисел никогда не должен приводить к столкновениям (в течение жизни Вселенной) и имеет произвольно высокую частоту изменений. - person Torsten Bronger; 16.04.2021
comment
FWIW, ARG CACHE_DATE= (без not_a_date) было достаточно для меня. - person Torsten Bronger; 16.04.2021

docker build --no-cache сделает недействительным кеш для всех команды.

Dockerfile ADD команда используется для отмены кеша. Хотя он был улучшен в последней версии докера:

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

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


В проблеме 1326 упоминаются другие советы:

Это сработало.

RUN yum -y install firefox #redo

Таким образом, похоже, что Docker повторно запустит этот шаг (и все шаги ниже), если строка, которую я передаю команде RUN, все равно изменится - даже это просто комментарий.

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

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

person VonC    schedule 03.08.2015
comment
Последняя версия докера? Этот комментарий был написан более года назад :) - person Adrian Mouat; 03.08.2015
comment
@Adr Согласен. Во времена докеров это выглядело так давно. - person VonC; 03.08.2015
comment
Подсказка: RUN yum -y install firefox #redo будет работать только с запуском, поскольку #redo не является комментарием файла докеров. Я случайно сломал материал, используя это, например, _3 _... - person the-bug; 18.03.2020

добавление && exit 0 после команды сделает кеш оттуда недействительным.

Пример:

RUN apt-get install -y unzip && exit 0

person rolele    schedule 11.03.2016
comment
Только что попробовал с Docker версии 1.12.0-rc2, не работает, все равно кешировать инструкцию - person Siyuan Zhang; 05.07.2016