Очистить кеш в Dockerfile без предоставления внешних аргументов сборки

У нас есть 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)) на этапе сборки?

Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
7
0
3 312
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете добавить 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.

Ответ принят как подходящий

Обновление: просмотрев это, похоже, что вы неправильно ввели параметр очистки кеша двумя способами:

  1. ENV не является ARG
  2. Синтаксис $(x) не является расширением переменной, вам нужны фигурные скобки (${}), а не круглые скобки ($()).

Чтобы сломать кеш на следующей строке запуска, используется следующий синтаксис:

ARG CACHE_BUST
RUN echo "command with external dependencies"

А затем построить с помощью:

docker build --build-arg CACHE_BUST=$(date +%s) .

Почему это работает? Потому что во время сборки значения для ARG вводятся в RUN команды как переменные среды. Изменение переменной среды приводит к промаху кеша в новой сборке.


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

Варианты обхода этого включают:

  1. Передача аргумента сборки, который изменяется (например, установка его на отметку даты).
  2. Изменение файла, который включается в образ, с помощью COPY или ADD.
  3. Запустите сборку с опцией --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, который позволит вам вводить явный разрыв кеша или уникальную переменную, которая приводит к разрыву кеша.

Другие вопросы по теме