У нас есть Dockerfile, где в определенный момент не хотелось бы кэширования.
В настоящее время мы используем
ENV CACHE_BUST=$($RANDOM)
При дальнейшем осмотре достаточно забавно, что кэшируется:
Step 1/1 : ENV CACHE_BUST=$($RANDOM)
---> Using cache
Есть ли способ изнутри Dockerfile сбросить кеш без прохождения уникального build-arg
(например, docker build . --build-arg CACHE_BUST=$(date +%s)
) на этапе сборки?
Вы можете добавить ADD
слой со скачиванием какой-либо динамической страницы из стабильного источника в начале Dockerfile
. Изображение всегда будет пересобираться без использования кеша.
Просто пример Dockerfile
:
FROM alpine:3.9
ADD https://google.com cache_bust
RUN apk add --no-cache wget
p.s. Я полагаю, вы знаете об опции docker build --no-cache
.
Обновление: просмотрев это, похоже, что вы неправильно ввели параметр очистки кеша двумя способами:
ENV
не является ARG
$(x)
не является расширением переменной, вам нужны фигурные скобки (${}
), а не круглые скобки ($()
).Чтобы сломать кеш на следующей строке запуска, используется следующий синтаксис:
ARG CACHE_BUST
RUN echo "command with external dependencies"
А затем построить с помощью:
docker build --build-arg CACHE_BUST=$(date +%s) .
Почему это работает? Потому что во время сборки значения для ARG
вводятся в RUN
команды как переменные среды. Изменение переменной среды приводит к промаху кеша в новой сборке.
Чтобы очистить кеш, нужно изменить один из входов. Если выполняемая команда та же самая, кеш будет использоваться повторно, даже если команда имеет измененные внешние зависимости, поскольку докер не может видеть эти внешние зависимости.
Варианты обхода этого включают:
--no-cache
.Поскольку вы не хотите выполнять вариант 1, есть способ выполнить вариант 3 в определенной строке, но только если вы можете разделить свой файл Dockerfile на 2 части. В первом Dockerfile есть все строки, которые есть у вас сегодня, вплоть до момента, когда вы хотите сломать кеш. Затем у второго Dockerfile есть строка FROM, которая зависит от первого Dockerfile, и вы создаете его с помощью опции --no-cache
. Например.
Докерфайл1:
FROM base
RUN normal steps
Dockerfile2
FROM intermediate
RUN curl external.jar>file.jar
RUN other lines that cannot be cached
CMD your cmd
Затем создайте с помощью:
docker build -f Dockerfile1 -t intermediate .
docker build -f Dockerfile2 -t final --no-cache .
Единственный другой вариант, о котором я могу думать, — это создать новый интерфейс с BuildKit, который позволит вам вводить явный разрыв кеша или уникальную переменную, которая приводит к разрыву кеша.