Moby: Запрос на новую функцию: выборочное отключение кеширования для определенных команд RUN в Dockerfile

Созданный на 24 сент. 2013  ·  245Комментарии  ·  Источник: moby/moby

ответвление обсуждения от # 1384:

Я понимаю, что -no-cache отключит кеширование для всего Dockerfile. Но было бы полезно, если бы я мог отключить кеш для конкретной команды RUN? Например, обновление репозиториев или загрузка удаленного файла ... и т. Д. Насколько я понимаю, прямо сейчас RUN apt-get update, если кэшировано, фактически не обновит репо? Это приведет к тому, что результаты будут отличаться от результатов на виртуальной машине?

Если отключить кеширование для определенных команд в Dockerfile станет возможным, будут ли последующие команды в файле не использовать кеш? Или они сделали бы что-то более интеллектуальное - например, использовали бы кеш, если предыдущая команда дала такие же результаты (слой fs) по сравнению с предыдущим запуском?

arebuilder kinfeature

Самый полезный комментарий

А как насчет CACHE ON и CACHE OFF в Dockerfile? Каждая инструкция будет влиять на последующие команды.

Все 245 Комментарий

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

Но разве это не ограничит с легкостью чередование кэшированных и некэшированных команд?

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

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

Разве это не было бы полезно?

А как насчет CACHE ON и CACHE OFF в Dockerfile? Каждая инструкция будет влиять на последующие команды.

Да, я использую команды git clone в моем Dockerfile, и если я хочу, чтобы он повторно клонировался с обновлениями, мне нужно, например, добавить комментарий в конце строки, чтобы вызвать перестройку из этого линия. Мне не нужно создавать совершенно новый базовый контейнер для этого шага.

Можно ли передать идентификатор контейнера в docker build в качестве инструкции «не кэшировать после этого идентификатора»? Подобно тому, как docker build кэширует все шаги вплоть до измененной строки в Dockerfile?

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

Я думаю, что это станет проще с грядущими расширениями API, в частности с именами и самоанализом.

Было бы отличной особенностью. В настоящее время я использую такие глупые вещи, как RUN a=a some-command , затем RUN a=b some-command чтобы сломать кеш

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

@shykes

Как насчет того, чтобы изменить --no-cache с логического значения на строку и использовать регулярное выражение для того, где в докере мы хотим перебрать кеш?

docker build --no-cache "apt-get install" .

Я согласен и предложил именно эту функцию в IRC.

За исключением того, что я думаю, чтобы сохранить обратную совместимость, мы должны создать новый флаг (скажем, "--uncache"), чтобы мы могли сохранить --cached как (устаревший) флаг типа bool, который разрешается в "--uncache. *"

Пт, 7 февраля 2014 г., в 9:17, Майкл Кросби [email protected]
написал:

@shykes
Как насчет того, чтобы изменить --no-cache с логического значения на строку и использовать регулярное выражение для того, где в докере мы хотим перебрать кеш?

docker build --no-cache "apt-get install" .

Ответьте на это письмо напрямую или просмотрите его на GitHub:
https://github.com/dotcloud/docker/issues/1996#issuecomment -34474686

Что все остальные думают об этом? Кто-нибудь готов реализовать эту функцию?

Я за то, чтобы попытаться реализовать это сегодня, если никто еще не начал?

Я начал над этим

  • Поле noCache в buildfile становится *regexp.Regexp .

    • Значение nil там означает то, к чему привык utilizeCache = true .

  • Передача строки в docker build --no-cache теперь отправляет проверочную строку регулярного выражения на сервер.
  • Просто вызов --no-cache приведет к значению по умолчанию .*
  • Затем регулярное выражение используется в новом методе buildfile.utilizeCache(cmd []string) bool для проверки команд, игнорирующих кеш.

Одно: насколько я понимаю, пакет flag / mflag не поддерживает строковые флаги без значения, поэтому мне нужно немного поиграть, чтобы поддержать как --no-cache и --no-cache some-regex

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

В любом случае, IANTM (я не сопровождаю), так что это всего лишь мои личные мысли. :)

@tianon --no-cache в настоящее время является логическим значением, поэтому это просто расширяет существующее поведение.

  • docker build --no-cache - то же поведение, что и раньше: игнорирует кеш
  • docker build --no-cache someRegex - игнорирует любые команды RUN или ADD , соответствующие someRegex

Хорошо, все в порядке. Проблема в том, что --no-cache является логическим значением, поэтому на самом деле существующее поведение таково:

  • --no-cache=true - явно отключить кеш
  • --no-cache=false - явно включить кеш
  • --no-cache - сокращение от --no-cache=true

Я также думаю, что мы окажем себе медвежью услугу, сделав строки регулярных выражений для особых случаев "true" и "false", чтобы решить эту проблему, поскольку это создаст потенциально неожиданное поведение для наших пользователей в будущем. («Когда я использую --no-cache с регулярным выражением« истина »или« ложь », это работает не так, как предполагалось!»)

@tianon да ты прав. Имел быстрый взгляд и люди используют = истина / ложь.

Рад изменить PR, чтобы добавить новый флаг, как вы предлагаете, что думают сопровождающие ( @crosbymichael , @shykes)? Это также означало бы, что я мог бы удалить код, добавленный к mflag, чтобы разрешить строковые / логические флаги.

+1 за подход @wagerlabs

@crosbymichael , @timruffles Не было бы лучше, если бы автор Dockerfile решал, какой шаг сборки следует кэшировать, а какой нет? Человек, создающий файл Dockerfile, не обязательно тот же человек, который создает образ. Перенос решения в команду docker build требует подробных знаний от человека, который просто хочет использовать определенный Dockerfile.

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

+1 за подход @wagerlabs

+1 для подхода @wagerlabs, хотя было бы еще лучше, если бы существовал способ кэширования бюста и на временном интервале, например

CACHE [interval | OFF]
RUN apt-get update
CACHE ON

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

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

FROM ubuntu:13.10
ADD ./files/cachebusters/per-day /root/cachebuster
...
ADD ./files/cachebusters/per-build /root/cachebuster
RUN git clone [email protected]:cressie176/my-project.git /root/my-project

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

Мой текущий план для решения этой проблемы - динамически вводить такие команды, как RUN echo 2014-04-17-00:15:00 с округлением сгенерированной строки до последних 15 минут, чтобы аннулировать элементы кеша при скачке округленного числа. аля каждые 15 минут. Это работает для меня, потому что у меня есть сценарий, каждый раз генерирующий файл докеров, но он не будет работать без этого сценария.

+1 за функцию.

Я тоже хочу проголосовать за эту функцию. Кеш раздражает при сборке частей контейнера из репозиториев git, который обновляется только в основной ветке.
: +1:

@hiroprotagonist Наличие git pull в вашем ENTRYPOINT может помочь?

@amarnus Я решил это аналогично идее @tfoote . Я запускаю сборку из задания jenkins, и вместо того, чтобы напрямую запускать команду docker build, задание запускает сценарий сборки, который генерирует Dockerfile из шаблона и добавляет строку RUN echo currentsMillies над командами git. Благодаря sed и трубам это было за несколько минут. В любом случае, я по-прежнему предпочитаю эту функцию как часть самого Dockerfile.

Добавление моего +1 для подхода @wagerlabs . Также возникла проблема с CI. Я пока просто использую динамический оператор echo RUN, но мне бы очень понравилась эта функция.

+1 для ВКЛЮЧЕНИЯ / ВЫКЛЮЧЕНИЯ КЭША. Мой вариант использования - это также автоматизация CI.

+1, особенно возможность установить интервал кеширования команд запуска, как в примере @ cressie176

«Например, обновление репозиториев или загрузка удаленного файла»

+1

Если это кому-то поможет, вот фрагмент кода, который я использую в своей сборке Jenkins:

echo "Using build $BUILD_NUMBER for docker cachebusting"
sed -i s/cachebust_[0-9]*/cachebust_"$BUILD_NUMBER"/g Dockerfile

+1 для ВКЛЮЧЕНИЯ / ВЫКЛЮЧЕНИЯ КЭША

Как возможная альтернатива подходу CACHE ON / OFF, как насчет дополнительного ключевого слова, такого как «ALWAYS». Ключевое слово будет использоваться в сочетании с существующей командой (например, «ВСЕГДА ВЫПОЛНЯТЬ» или «ВСЕГДА ДОБАВИТЬ»). По замыслу, ключевое слово «ALWAYS» не попадает в кеш для выполнения соседней команды. Тем не менее, он сравнивает результат с CACHE (неявно кэш в других случаях, когда выполнялась та же строка), связываясь с кешированным изображением, если результат команды ALWAYS не изменился.

Я считаю, что основная потребность заключается в выявлении «неидемпотентных инструкций» . Команда ALWAYS делает это очень явно. У меня сложилось впечатление, что подход CACHE ON / OFF может работать одинаково хорошо, но также может потребовать большого количества переключений блоков кода (что может побудить пользователей заблокировать больше строк, чем действительно требуется).

Я также больше за префикс для команд, например ALWAYS или CACHE 1 WEEK ADD ...

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

From ubuntu:14.04

RUN apt-get -yqq update
RUN apt-get -yqq install git
RUN git clone https://github.com/coreos/fleet
ADD http://www.random.org/strings/?num=10&len=8&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new uuid
RUN cd fleet && git pull

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

Еще один +1 за подход @wagerlabs

Еще один +1 к этой функции. Между тем, используя обходной путь

еще один +1 за запрос функции. И спасибо @cruisibesarescondev за обходной путь

Еще +1 за эту функцию.

Приветствую @cruisibesarescondev за обходной путь.

Я думаю, что ключевое слово ALWAYS - хороший подход, тем более что у него простая и понятная семантика. Немного более сложный подход - добавить минимальное время (полезно в таких вещах, как сборочная ферма или непрерывная интеграция). Для этого я бы предложил синтаксис «КАЖДЫЙ ХХХ», где ХХХ - это время ожидания. И если с момента создания кеша этой команды прошло больше XXX, он должен выполнить команду повторно. И проверьте, не изменился ли вывод. Если нет изменений, повторно используйте кешированный результат с указанием времени последнего обновления. Это означало бы, что КАЖДЫЙ 0 будет таким же, как ВСЕГДА.

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

@{
import time
def cache_buster(seconds):
    ts = time.time()
    return ts - ts % seconds
}@

Где я хочу принудительно запустить повтор:

RUN echo @(cache_buster(60))

Что выглядит так в Dockerfile

RUN echo 1407705360.0

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

+1 для ВСЕГДА синтаксиса. +,5 для CACHE ON / CACHE OFF.

+1 для ВСЕГДА синтаксиса.

Да, ВСЕГДА синтаксис выглядит очень интуитивно понятным.

Мне не нравится CACHE ON / OFF, потому что я думаю, что строки должны быть «самодостаточными», а добавление блоков в Dockerfiles может вызвать множество «проблем» (например, необходимость проверки «покрыта ли эта строка кешем?» При слиянии .. .).

@kuon Я думаю, что уже есть ряд команд, которые влияют на последующие инструкции, например USER и WORKDIR

Да, это правда, но я не использую их по той же причине. Я всегда делаю RUN cd ... && или RUN su -c ...&& .

Я бы предпочел блочную запись:

CACHE OFF {
    RUN ...
}

Это более явный вариант и позволяет избежать ошибочной вставки строки CACHE OFF (это может вызвать синтаксическую ошибку).

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

Возможно, эта проблема связана с новым форматом Dockerfile.

Я хотел бы вернуться к тому, что только что сказал. Я прочитал, что сказал @shykes в другом выпуске https://github.com/docker/docker/pull/2266, и я также согласен с ним (Dockerfile должен оставаться действительно простой сборкой, например языком).

Я сказал, что мне нужна переменная или что-то в этом роде, но это может быть покрыто другим языком, но в этом случае каждая строка в Dockerfile должна быть автономной, например:

NOIMAGE ALWAYS RUN USER:jon  apt-get update

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

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

Может быть, это будет RUN! для удобства, пожалуйста?

Есть ли обновления статуса по этому поводу?

Выборочное отключение кеша было бы очень полезно. Я беру файлы из удаленного репозитория amazon s3 с помощью команды awscli (из инструментария Amazon AWS), и у меня нет простого способа перебрать кеш с помощью команды ADD (по крайней мере, я не могу придумать способ без редактирования файла Dockerfile. чтобы вызвать его). Я считаю, что есть веские основания вернуть управление пользователю для выборочной очистки кеша при использовании RUN. Если у кого-то есть предложение для меня, я был бы рад услышать от вас.

Хотел немного поднять эту проблему, так как это то, в чем мы очень нуждаемся.

Тем не менее убежден, что синтаксис ALWAYS является идеальным.

Как насчет простой инструкции BREAK .

@ cpuguy83 , который также

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

Однако наличие поддержки BREAK дало бы мне функциональный паритет с моим текущим обходным путем, основанным на предложении @CheRuisiBesares.

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

@orrery Вы, вероятно, могли бы " COPY _before_ этого шага сборки. Если скопированные файлы отличаются, все последующие шаги больше не должны использовать кеш (см. Этот раздел ). Грязный трюк, но может решить ваше дело.

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

  • Цель состоит в том, чтобы гарантировать, что мы прекратим использование кеша, если и когда результат команды (например, «обновить до самой последней версии») изменится.
  • Напротив, если результат соответствует кэшированной версии, мы хотим воспользоваться кешем.

Это касается комментария @hellais, поскольку вы можете воспользоваться кешем для последующих команд ... тогда и только тогда, когда вывод ALWAYS соответствует кэшированной версии (это может быть легко в большинстве случаев).

Естественно, такая же логика _ могла_ быть включена в модель CACHE ON / OFF. Сравнение с кешем, вероятно, будет дешевле, чем повторный запуск всех последующих команд, но все же может быть дорогостоящим. Если блок CACHE ON / OFF побуждал пользователя включать дополнительные команды в блок OFF (что не может произойти с ALWAYS ), это могло способствовать значительным различиям в производительности.

Я нахожусь в той же ситуации, что и @tfoote : я использую Docker для CI, и мне нужно принудительно истечь срок действия кеша.

+1 для синтаксиса EVERY . Синтаксис ALWAYS также выполнит свою работу.

@claytondaley , это отличный

@mkoval , вы подняли хороший вопрос о _создании _ скрытых состояний как важный момент для использования ALWAYS , но я не думаю, что это влияет на мою логику возобновления кеширования. Чтобы сделать пример конкретным (хотя и несколько тривиальным), команда, обновляющая стороннюю систему:

  • Создает скрытое состояние (необходимо запустить ALWAYS ) и
  • Не меняет текущий контейнер

Если следующая команда не включает скрытое состояние (тривиально, команда mv в контейнере), кеш будет надежным на 100%. Тот же контейнер, та же команда, никакой зависимости от скрытой информации.

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

@claytondaley ваше решение кажется мне очень элегантным и эффективным. Буду очень признателен, если это будет реализовано. : +1:: осьминог:

+1 для этой функции с использованием ВСЕГДА и КАЖДОГО X предложенного синтаксиса. CACHE ON / OFF кажется мне немного неуклюжим, но я бы использовал его. Мне также очень нравится предложение @claytondaley возобновить кеш там, где это возможно.

+1 для ВСЕГДА синтаксиса. особенно для кодов вывода из репозитория git.

+1 Для любого из этих решений.

Я немного запутался. Как можно снова включить кеширование после его отключения? После того, как вы выключите его и внесете какие-либо изменения в контейнер, не приведет ли повторное включение кеширования к отбрасыванию любых изменений, внесенных теми командами Dockerfile, которые выполнялись при отключенном кешировании? Я думал, что единственная причина, по которой мы могли выполнять кэширование, заключалась в том, что мы точно знали полный список предыдущих команд, которые были запущены, и могли гарантировать, что то, что было в контейнере, было точно таким же. Если вы отключите кеширование (а я говорю о его поисковой стороне), разве это не уничтожит вашу гарантию? Или дело в том, что кеш просто не заполняется?

Насколько я понимаю, вы можете указать «ВСЕГДА» как часть команды Dockerfile, чтобы всегда запускать шаг снова. Например, «ВСЕГДА запускать git clone https://example.com/myrepo.git » всегда будет выполняться (тем самым всегда клонируя репо). Тогда что предлагает @claytondaley, так это то, что после повторного запуска этой команды Docker проверяет изменения по кешу. Если контрольная сумма такая же (т.е. если в клонированном репо не было изменений, поэтому самый новый уровень идентичен тому же уровню в кеше), мы можем продолжить работу с кешем. Вы правы, что после того, как кеш становится недействительным, все последующие шаги не могут использовать кеш. Эти предложения просто обеспечивают более детальный контроль над тем, когда использовать кеш, а также позволяют возобновить работу из кеша там, где это возможно.

@curtiszimmerman ... именно так

@duglin ... Идея может быть более очевидной, если мы воспользуемся математическим прокси. Кэш (в данном контексте) - это просто память о результате action B при применении к state A поэтому вам не нужно его повторно обрабатывать. Предположим, я запускаю последовательность команд:

  • начать с 6
  • ВСЕГДА запускайте * x где значение x загружается из репозитория git (и, следовательно, может измениться)
  • запустить + 12

В первый раз, когда я запускаю команду, x равно 8, поэтому я получаю (и кэширую) следующую последовательность:

  • 6
  • 48 (в результате применения * x к 6 )
  • 60 (в результате применения + 12 к 48 )

Если моя машина когда-либо снова достигает состояния 48 (любой последовательностью) ... и получает команду + 12 , мне больше не нужно выполнять обработку. Мой кеш знает, что результатом этой команды будет 60 .

Сложнее всего выяснить, когда вы снова находитесь в том же состоянии ( 48 ).

  • Теоретически мы могли бы сравнивать машину после каждой команды с любым другим кэшированным изображением, но это требует больших ресурсов и имеет очень низкие шансы найти совпадение.
  • Мое предложение - не усложнять. Каждый раз, когда мы находимся в состоянии (например, 6 ) и нажимаем команду (например, * x ), мы сравниваем результат с кешем последнего раза (или раз), когда мы были в том же состоянии. выполнение той же команды. Если состояние машины после этого процесса такое же (например, все еще 48 ), мы возобновляем кеширование. Если следующая команда по-прежнему + 12 , мы извлекаем результат из кеша, а не обрабатываем его.

@claytondaley, но я не понимаю, как вы определяете текущее состояние. Как вы сказали, мы не сравниваем все файлы в контейнере. Теперь кеш работает просто так: просто strcmp следующую команду, которую мы хотим запустить для всех известных дочерних контейнеров из текущего контейнера. В ту минуту, когда вы пропускаете контейнер в потоке, я не понимаю, как вы можете предположить, что ваш текущий контейнер похож на любой другой кэшированный контейнер без проверки всех файлов в файловой системе. Но, возможно, я не понимаю, что вы делаете.

Позвольте мне перефразировать это .... учитывая случайный контейнер (который в основном то, что у вас есть, если вы не используете кеш), как вы можете найти контейнер в кеше, который соответствует ему, без сравнения всех файлов в контейнер?

@claytondaley @duglin Определение возможности кэширования операции «без кеша» из-за отсутствия изменений - сложная проблема, как вы описали. Кроме того, это скорее приятное занятие, чем необходимость.

Лично я был бы более чем счастлив, если бы все, что у меня было, - это возможность гарантировать, что команда всегда выполняется. Возьмите Dockerfile, например:

RUN install_stuff_take_forever
RUN always_do_it   #will not run every time
RUN more_stuff

В настоящее время строка always_do_it будет запускаться только в первый раз, если я не отредактирую текст для принудительной блокировки кеша. Я думаю, большинство из нас были бы счастливы согласиться с тем, что more_stuff иногда будет запускаться без необходимости (когда always_do_it не изменилось, если взамен мы можем сохранить кеш для install_stuff_take_forever .

RUN install_stuff_take_forever
NOCACHE
RUN always_do_it
RUN more_stuff

@pikeas Я полностью понимаю команду NOCACHE, и это легко сделать. Чего я не получаю, так это команды, которая включает его обратно без сравнения / хеширования / любой файловой системы.

Я прочитал "слоистое" объяснение Docker, означающее, что:

  • Docker создает «слой» для каждой команды.
  • Этот уровень включает в себя только файлы, измененные (или, возможно, «сохраненные» вне зависимости от того, были ли они изменены или не изменены) этой командой.
  • Текущее состояние файловой системы логически (если не оперативно) достигается путем проверки каждого уровня по порядку до тех пор, пока он не найдет (самую последнюю обновленную) версию этого конкретного файла.

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

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

  • В большинстве случаев (git pull или обновление программного обеспечения) текущая версия будет либо (1) такой же, как и предыдущие версии, либо (2) новой версией ... но никогда - по крайней мере, редко - откатом к предыдущей версия.
  • В редких случаях (например, при обновлении до dev-master с последующим возвратом к стабильной версии) можно вернуться к более старой версии. Однако это довольно редко, поэтому большинству людей, вероятно, будет лучше (часто) проверять только самую последнюю версию и повторно запускать команды в тех редких случаях, когда они откатываются.

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

если вы посмотрите внизу https://github.com/docker/docker/pull/9934, вы увидите обсуждение опций поддержки команд Dockerfile. Что, если бы для всех (или даже только RUN) была доступна опция --no-cache, означающая «не использовать кеш» для этой команды? например:
ВЫПОЛНИТЬ --no-cache apt-get install -y мой-любимый-инструмент
Затем это автоматически отключит кеш и для остальных команд (я думаю).
Решит ли это проблему?

Между семантически идентичными «RUN ALWAYS» и «RUN --no-cache» я бы предпочел более естественный синтаксис «RUN ALWAYS». Я согласен с последним комментарием к этому PR: я думаю, что --option нарушает удобочитаемость и сделает файлы Docker некрасивыми. Кроме того, я думаю, что команды Dockerfile должны сильно отличаться от фактических команд, которые следуют за ними. Представьте себе что-то вроде «RUN --no-cache myapp --enable-cache» для одного примера запутанного синтаксиса, который начал бы быстро выражаться с помощью такого рода параметров.

@curtiszimmerman мне очень понятен твой пример. --no-cache для RUN, а --enable-cache для myapp. Размещение имеет значение. Например, посмотрите:
docker run -ti ubuntu ls -la
люди понимают, что -ti означает «запускать», а -la - для «ls». Людям кажется, что этот синтаксис удобен.
Одна из проблем с чем-то вроде RUN ALWAYS - это расширяемость. Нам нужен синтаксис, который может работать для всех команд Dockerfile и поддерживать передачу значения. Например, люди выразили заинтересованность в указании ПОЛЬЗОВАТЕЛЯ для определенных команд.
ЗАПУСК ПОЛЬЗОВАТЕЛЯ = foo myapp
технически устанавливает env var USER на 'foo' в оболочке myapp. Итак, мы здесь двусмысленны.
Хотя: RUN --user = foo У моего приложения нет этой проблемы.
Это: RUN var = foo myapp
пытаетесь установить и env var под названием 'var' или опечатку пытаетесь получить какую-то опцию RUN?
IOW, шансы совпадения с существующей действующей командой, IMO, намного меньше, когда мы начинаем с - чем просто разрешить слово там

На самом деле я выступаю за обратную последовательность, EVERY <options> COMMAND . Некоторые причины:

  • В случае «пользователь» и «кеш» (по крайней мере), это действительно характеристики среды, которые могут обернуть любую КОМАНДУ (хотя они не могут существенно повлиять на другие).
  • Синтаксис RUN ALWAYS означает изменение интерпретатора команд RUN , что кажется ненужным.
  • Эта проблема еще хуже с RUN EVERY 5 days потому что параметры, прикрепленные к КАЖДОМУ, создают еще большую двусмысленность. EVERY 5 days RUN ясно говорит о команде, на которую влияют параметры. У нас та же проблема с RUN USER usr vs. USER usr RUN . Пока либо (1) ключевые слова команды никогда не являются параметрами, либо (2) есть простой способ избежать их, это однозначно.

Я мог бы заняться префиксом команд с их параметрами ( ALWAYS AS user RUN ... ). Меня просто беспокоит использование лонгоптов в стиле GNU для опций, потому что они не очень отличаются от старых или затуманенных глаз. Я могу представить, что смотрю на сложную команду Dockerfile после 20 часов, размышляя о том, что происходит. Но я предсказываю - варианты все равно будут.

Но я предсказываю - варианты все равно будут.

Напротив, пока ничего не решено; синтаксис, предлагаемый @duglin, является _счетчиком_ синтаксиса, который был предложен / выбран ранее. Пожалуйста, прочтите # 9934 для получения дополнительной информации об этом.

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

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

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

И да, ваше мнение по этому поводу приветствуется.

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

Наличие флага "docker build" для остановки кеширования в определенном месте
было бы гораздо более гибким, ИМО (и вернуть контроль над кешем
в руки системного оператора, который так или иначе будет управлять этим кешем).

+1 на -1 @tianon (так что это -1!), И добавление флага для прерывания на шаге N кажется разумным. Учитывая, что после того, как кеш сломан, он в любом случае сломается для остальной части файла Dockerfile, я думаю, что это имеет смысл.

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

Не говоря уже о том, что я думаю об этой функции - пока не уверен, если честно - как вы, ребята, представляете, как кто-то скажет (из "docker build") остановиться на шаге N? Кажется хрупким, когда сегодня шаг N будет шагом N + 1 завтра.
Похоже, нам может понадобиться способ добавить какую-то «метку» в Dockerfile, чтобы люди могли ссылаться на эту метку из строки build cmd.
Если бы у нас было это, я не уверен, что вижу большую разницу между этим и добавлением команды «STOP-CACHING», которая появляется в Dockerfile.
Какой хороший пример Dockerfile cmd, который каждый раз перебирает кеш?

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

Тианон Грави [email protected] написал:

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

Я хотел бы повторить свое предыдущее предложение, что ВСЕГДА / нарушение кеширования
"RUN" должно быть просто "RUN!" чтобы сохранить структуру команды из 1 слова (?).

Кажется глупым редактировать Dockerfile (добавляя что-то, что в основном случайное, потому что это заполнитель), чтобы сломать кеш на определенном шаге. Я бы использовал параметр docker build CLI, который всегда выполняет определенный шаг, но полностью согласен с @duglin, что необходимость отслеживать конкретный номер строки, чтобы git clone просто чтобы подтолкнуть Docker к фактическому клонированию репо вместо работы из кеша.

@curtiszimmerman Я предложил (!), потому что это указывает на что-то вроде срочности на английском языке. («Вы должны СДЕЛАТЬ ЭТО!»)

Я думаю, что файл Dockerfile - это по крайней мере одно подходящее место для определения того, какие команды должны быть отключены / кешированы. Необходимость создавать с помощью "--no-cache = git" (я понимаю, что это не то, что вы предлагали, но вы не предлагали мне ничего, что можно было бы процитировать / сравнить) кажется более неуклюжим.

Почему упор на БЕГ? Почему бы не позволить кешу быть заблокированным для любой команды?
Похоже на добавление:
БЮСТ-КЭШ
тип команды Dockerfile был бы гораздо более гибким. И чтобы действительно добавить гибкости, он может дополнительно разрешить флаг:
БЮСТ-КЭШ $ doit
где он применяется только в том случае, если $ doit определен - тогда, если мы добавим поддержку опции -e при сборке (https://github.com/docker/docker/pull/9176), тогда люди могли бы сделать:
docker build -e doit = ​​true ...

@zamabe О, я бы полностью использовал RUN! , извините. Здесь я использовал (!), Чтобы сказать "Это необычно!" о редактировании Dockerfile каждый раз, когда я хочу сломать кеш на определенном шаге. В любом случае я мог бы перебрать кеш внутри Dockerfile до того, как конкретный шаг будет полезен (и для дополнительной победы, если шаг после этой команды очистки кеша будет таким же, как и то, что находится в кеше, будьте достаточно умны, чтобы продолжить из кеша ). BUST-CACHE или ALWAYS RUN (или RUN ALWAYS ) или RUN! ... На самом деле любой механизм, поддерживающий эту функцию, я бы использовал.

@duglin Извини? В заголовке ошибки написано RUN, что проще привести в качестве примера.

@curtiszimmerman ах.

Как в сторону; Я думаю, что повторная проверка кеша (?) Немного выходит за рамки недействительности кеша, которую ищет эта ошибка. Хотя мне нравится то, что вы предлагаете, я бы просто переупорядочил свой Dockerfile, чтобы поместить команды очистки кеша как можно ближе к концу. Это сводит на нет преимущества, полученные от _возможного_ попадания в кеш, поскольку вы _ всегда_ выполняете необходимые вычисления / сравнения, что, вероятно, является более тяжелым наказанием, чем обычное завершение сборки Dockerfile, поскольку люди, использующие очистку кеша, вероятно, надеются / ожидают промаха кеша.

@zamabe Согласен. Я предлагаю, если реализация довольно тривиальна для этого, возможно, специальная команда для продолжения из кеша, которая отделена от идентификатора блокировки кеша. Что-то вроде DISABLE-CACHE в определенный момент, чтобы каждый раз отключать кеш, и если у вас есть вариант использования, когда остальная часть Dockerfile будет дорогостоящей по сравнению с продолжением из кеша, что-то вроде DISABLE-CACHE? будет если возможно, продолжить из кеша. Это не предложение, а просто демонстрация того, о чем я говорю.

+1 для кодов извлечения из репозитория git

+1

Это было бы здорово! Прямо сейчас у меня есть часть моей непрерывной интеграции, записывающей хеш коммита git в Dockerfile (перезаписывая заполнитель), просто чтобы сломать кеш для клонов git.

Я отправил этот PR: https://github.com/docker/docker/pull/10682, чтобы решить эту проблему.
Хотя он не поддерживает повторное включение кеширования, я не думаю, что сегодня это возможно.

+1

Я генерирую случайное число в Dockerfile, и оно кешируется ...
+1 за инструкцию NOCACHERUN

+1
Должно быть действительно полезно для некоторого RUN, который нам нужно делать каждый раз, не перестраивая все

Я заметил, что git clone попадет в кеш, а go get -d - нет. какие идеи почему?

_Коллективный обзор с @ LK4D4 @calavera @jfrazelle @crosbymichael @tiborvass_

Заканчивая это, мы не видим так много реальных случаев использования (см. Связанный # 10682 для более подробной информации).

+1 за БЕГ. Было бы здорово.

+1

docker 1.9 вводит переменные времени сборки; их можно (неправильно) использовать для принудительного взлома кеша; для получения дополнительной информации см. https://github.com/docker/docker/issues/15182

Как это еще не функция?

@ hacksaw6 Вы можете посмотреть, что было сказано здесь: https://github.com/docker/docker/pull/10682

+1

+1

+1 как это еще даже не штучка !!! ???!

+1 Нам нужна эта функция, чтобы обеспечить более детальный контроль над строительством.

+1

+1

+1

+1

+1 очень полезно
(на данный момент используется обходной путь

+1

+1

+1

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

+1, прибыл сюда через Google в поисках решения проблемы клона git в кэше.

Мой вариант использования:
У меня есть конфигурация докера, которая во время сборки будет вызывать через gradle отличное приложение для микросервисов в режиме пробного запуска. В результате все зависимые библиотеки java (из удаленного репозитория mvn) будут загружены в локальный репозиторий docker mvn. Пробный прогон просто запустит приложение и немедленно вернется, но гарантирует, что все зависимости библиотеки Java загружены.
Во время фазы запуска докера это же приложение будет выполняться в режиме gradle --offline. Т.е. приложение микросервиса просто загрузится из локального каталога репозитория mvn. не будет происходить дорогостоящая и трудоемкая загрузка удаленной библиотеки. Когда я сейчас выпускаю новую версию такой библиотеки, докер не будет запускать удаленную выборку во время сборки (т. Е. Он не будет вызывать мой gradle dryrun cmd), если я не изменю каталог докера.

Мой вариант использования: получить последнюю стороннюю версию библиотеки для использования с изображением. Я использую для этого docker hub и AFAIK, он ничего не кеширует. Но кто знает, когда это может измениться.
Если бы в докере был такой флаг команды, как NOCACHE, это гарантировало бы это независимо от того, где создается образ.

ИМХО хуже зависеть от "фичи" системы сборки, чем от последней версии.

Как насчет добавления нового синтаксиса: FORCE RUN git clone .... ?

Прямо сейчас я использую RUN _=$(date) git clone ... для недействительности кеша.

@ c9s это действительно работает? Я не думаю, что это так.

У меня работает переменная среды настройки

@ c9s Я не понимаю, как может работать установка env var, поскольку это делается оболочкой контейнера, а не обработкой Dockerfile. Когда я пробую RUN _=$(date) echo hi он использует кеш второй сборки.

@duglin ты прав: | это не делает кеш недействительным

@ c9s попробуйте это вместо этого

FROM foo
ARG CACHE_DATE=2016-01-01
RUN git clone ...
docker build --build-arg CACHE_DATE=$(date) ....

@thaJeztah Спасибо! оно работает!

+1 клонирование репозиториев git (вариант использования)

Так много +1, что если вы вытащите репозиторий git в свой файл докера, кеш не позволит вашим изображениям собираться. Сложно продвигать сборки через CI.

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

@Vingtoft Если вы обновляете файлы в репо, ваш кеш становится недействительным.

@itsprdp Я этого не знал, спасибо за разъяснения.

@itsprdp Я только что протестировал. Когда я обновляю репо и создаю образ, Docker все еще использует кеш.
Может я что-то недопонимаю?

@itsprdp По моему опыту, это неверно. Я сделал новую фиксацию репо для тестирования, и при повторном построении он использует тот же кеш.

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

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

@itsprdp Было бы подойдет .
В моем варианте использования (и во многих других) на самом деле git pull не занимает много времени: это создание всего остального, что убивает процесс разработки.

+1, кеш использовался во время git clone :(

Интегрированное решение было бы неплохо, но пока вы можете перебрать кеш с помощью конкретной инструкции Dockerfile с помощью ARG .

В Dockerfile:

ARG CACHEBUST=1
RUN git clone https://github.com/octocat/Hello-World.git

В командной строке:

docker build -t your-image --build-arg CACHEBUST=$(date +%s) .

Установка CACHEBUST на текущее время означает, что оно всегда будет уникальным, а инструкции после объявления ARG в Dockerfile не будут кэшироваться. Обратите внимание, что вы также можете выполнить сборку без указания аргумента CACHEBUST build-arg, что приведет к использованию значения по умолчанию 1 и сохранению кеша. Это можно использовать, чтобы всегда проверять свежие копии репозиториев git, извлекать последние зависимости SNAPSHOT и т. Д.

Изменить: Это именно то, что сказал @thaJeztah . Я оставлю это как дополнительное описание его решения.

@ shane-axiom Как насчет использования хеша коммита git в качестве значения для CACHEBUST ?

export CACHEBUST=`git ls-remote https://[email protected]/username/myRepo.git | grep refs/heads/develop | cut -f 1` && \
echo $CACHEBUST && \
docker build -t myDockerUser/myDockerImage \
   --build-arg blah=blue \
   --build-arg CACHEBUST=$CACHEBUST \
   .

На основе подсказок из http://stackoverflow.com/questions/15677439/how-to-get-latest-git-commit-hash-command#answer -15679887

@pulkitsinghal. Прекрасно

+1 для CACHE ON | ВЫКЛЮЧЕННЫЙ

+1

+1

Помните о подходе @CheRuisiBesares , вы всегда можете использовать ADD https://www.random.org/strings/?num=16&len=16&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new uuid качестве обходного пути для проблем с кешем.

Чтобы опубликовать дополнительный вариант использования ....

COPY package.json /usr/src/
RUN npm install

В нашем package.json мы обычно будем указывать на тег master для некоторых наших частных зависимостей github. Это означает, что мы никогда не получим последний master если не изменим файл package.json (обычно просто добавляем к описанию - а затем удаляем его во время тестирования).

RUN NO CACHE вместо RUN кажется хорошим решением.

+1

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

Было бы здорово, если бы я мог отключить кеш для каждой команды RUN в файле докера.

@brycereynolds @mmobini см. https://github.com/docker/docker/issues/1996#issuecomment -172606763 для ручной очистки кеша. Однако _не_ указание конкретной версии пакетов, которые необходимо установить, может быть не лучшей практикой, поскольку конечный результат вашего Dockerfile (и исходного кода) больше не гарантированно воспроизводится (т. Е. Он успешно собирается сегодня, но не работает). Не завтра, потому что один из пакетов обновился). Я вижу, что это «нормально» во время разработки, но для производства (и автоматизированных сборок на Docker Hub) лучший подход - явно указать версию. Это также позволяет пользователям проверить точные пакеты, которые использовались для создания образа.

У меня есть случай использования, когда невозможность сделать кеш недействительным вызывает проблемы. Я запускаю приложения Dropwizard (службы Java REST, созданные с помощью Maven) из Docker, и автоматизированная система выполняет все сборки и развертывание контейнеров за меня. Я включаю Dockerfile в свое репо, а он делает все остальное. В системе работает производственная версия и одна или несколько разрабатываемых версий моего приложения. У меня возникают проблемы со сборками для разработки.

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

@ctrimble Вы можете использовать --no-cache или --build-arg чтобы сделать кеш недействительным.
Вы можете минимизировать эффект --no-cache , имея базовое изображение со всеми кэшируемыми командами.

@ cpuguy83 спасибо за ответ. Я прочитал ветку и понимаю текущие варианты. Я открыл заявку с системой сборки, которую использую, чтобы предоставить аргумент очистки кеша. Создание двух разных изображений для одного приложения кажется сложной задачей, чтобы ускорить сборку. Было бы намного проще указать что-то вроде:

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

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

@ctrimble Очистка кеша на одном шаге приведет к тому, что кеш всегда будет остановлен на каждом последующем шаге.

@ cpuguy83 точно. Семантика моей системы сборки временна для сборок разработки. Мне нужно выбрать правильные сборки вместо кеширования. Я бы очень хотел получить и то, и другое.

Здесь было много дискуссий, извиняюсь, если это уже было предложено, но что, если было что-то вроде этого:

CHECK [FILE_PATH]

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

Я бы, наверное, сделал что-то вроде:

CHECK Gemfile
CHECK package.json
CHECK composter.json
CHECK project.json

Также может потребоваться включить проверку, которая каким-то образом проходит по прошествии определенного периода времени. Параметр Ansible cache_valid_time для плагина apt может вдохновить: http://docs.ansible.com/ansible/apt_module.html

Для этого синтаксис будет следующим:

EXPIRE 1234567 
RUN apt-get update
RUN bundle install

Docker будет знать время последнего запуска и вычислять, истекло ли время, исходя из «сейчас».

@atrauzzi Мы просто поддерживаем --squash при сборке в 1.13 (пока только экспериментально).

@ cpuguy83 Есть ли где-нибудь документы или объяснения по поводу --squash которые я могу прочитать? Вначале название не похоже на то, что я думаю. Но я мог ошибаться (и, скорее всего, ошибаюсь)!

@atrauzzi да, в ссылке на сборку.

По сути, --squash сохраняет кеш слоев и создает второе изображение, как если бы все в Dockerfile происходило на одном уровне.

Я не понимаю, почему нужно проверять, что файловый кеш по-прежнему действителен индивидуально, ADD и COPY уже делают это для всего, что копируется.

@ cpuguy83 Хорошее замечание, даже не подумал об этом, и, конечно, уже пользуюсь.

А как насчет подхода с отметкой времени / продолжительности? Это можно сделать с тем, что уже доступно?

А как насчет подхода с отметкой времени / продолжительности? Это можно сделать с тем, что уже доступно?

Через build-args;

ARG expire_after=never
RUN do some thing
docker build --build-arg expire_after=2016-12-01 -t foo .

измените аргумент сборки, чтобы очистить кеш

+1 за более чистый способ

+1 за более чистый способ

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

+1

Могу я предложить передать номер шага команде сборки?

Что-то вроде этого:
docker build --step 5 .

Он проигнорирует все кеши после шага 5 во время сборки и включит его.

+1
Пожалуйста.

КЭШ ВКЛ | ВЫКЛ +1

Проблема с этими командами CACHE ON|OFF заключается в том, что на каком бы этапе кеш ни был отключен, кэшировать дальнейшие шаги невозможно. Единственная разумная команда - ENDCACHE .

Это действительная идея / этос. Предполагается, что команда объединит все некэшированные слои в один слой в момент, когда кеш снова включается. Конечно, вы все еще можете спорить о лучшем наименовании / правильности семантики / предпочтительном синтаксисе функции.

+1

+1 обязательная функция

Согласитесь на CACHE ON | OFF +1

+1 Было бы здорово.

Я действительно не понимал, как Docker кэширует шаги раньше, и потратил полдня, исследуя, почему моя система не строится правильно. Это было кеширование «git clone».

Хотелось бы иметь ключевое слово ALWAYS .

Как это закрыто?

Какое решение лучше всего?

Я пробовал https://github.com/moby/moby/issues/1996#issuecomment -185872769, и это сработало
В Dockerfile:

ARG CACHEBUST=1
RUN git clone https://github.com/octocat/Hello-World.git

В командной строке:

docker build -t your-image --build-arg CACHEBUST=$(date +%s)

Почему бы не создать новую команду, аналогичную RUN, но никогда не кэшировать RUNNC для RUN NO CACHE?

Могу подтвердить, @habeebr (https://github.com/moby/moby/issues/1996#issuecomment-295683518) - я использую его в сочетании с https://github.com/moby/moby/issues/1996# комментарий -191543335

+1

RUNNC - отличная идея!

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

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

Единственный другой аргумент, который я слышал в пользу закрытия этого, заключается в том, что есть другие способы добиться этого ... но этот аргумент также не проходит проверку. Создание нескольких базовых образов с единственной целью обойти отсутствие контроля над кешем громоздко, а создание недействительности с помощью ARG - глупо и неинтуитивно. Я полагаю, что пользователи хотят использовать эти «обходные пути» примерно столько же, сколько разработчики Docker хотят официально включить небрежный взлом в инструмент.

это не сложно: https://github.com/moby/moby/pull/10682
простое решение, легкий UX. Просто нет четкого консенсуса по поводу того, нужно ли это делать.

Вау просто вау...

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

+1

+1 для разумной безопасности и лучшей производительности

+1

+1

+1

+1

+1

+1

Вы можете перестать спамить +1? Просто используйте функцию реакции, чтобы проголосовать за.

Любые изменения?
До сих пор не знаю, почему этот вопрос закрыт.
На мой взгляд, это обязательная функция, которая отлично справляется с извлечением версии из удаленного репозитория git.

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Зачем закрывать это? Я думаю это полезно

+1

+1

+1

На данный момент самый простой способ отключить кеш для слоя (и следующих):

Dockerfile

ARG CACHE_DATE
RUN wget https://raw.githubusercontent.com/want/lastest-file/master/install.sh -O - | bash

И когда вы создаете образ, нужно добавить --build-arg

docker build  --build-arg CACHE_DATE="$(date)"

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

RUNNC или CACHE OFF было бы неплохо

Между тем, это выглядит многообещающим:
http://dev.im-bot.com/docker-select-caching/

это:

screenshot 2018-05-26 19 03 09

я пойду успокойся и присоединюсь к стаду:

+1

Да, мне нужно выборочное кеширование команд. Мой COPY выходит из строя в 80% случаев, если я изменяю только одно слово в файле конфигурации. Я бы не хотел кэшировать свои COPY а все остальное. Было бы здорово иметь CACHE ON и CACHE OFF .

RUN X
RUN X
CACHE OFF
COPY /config /etc/myapp/config
CACHE ON

@shadycuz Вы никогда не сможете «повторно включить» кеш после отключения / аннулирования его каким-либо методом. Сборка не сможет проверить (за разумный промежуток времени с разумным объемом ресурсов), что некэшированный уровень не изменил что-то еще в файловой системе, что необходимо учитывать в новых слоях. Чтобы свести к минимуму влияние необходимости всегда извлекать внешний файл конфигурации, вы должны поместить свою директиву COPY как можно глубже в файл Docker (чтобы Docker мог использовать кеш сборки для большей части процесс сборки до того, как кеш станет недействительным).

Чтобы сделать кеш недействительным на определенном этапе процесса сборки, вы можете обратиться к любому из других комментариев об использовании --build-arg и ARG упомянутых здесь ранее.

@shadycuz @curtiszimmerman Да, мы можем сохранить только CACHE OFF но не CACHE ON , потому что следующие слои необходимо перестроить, если предыдущий слой был изменен.

Я согласен с тем, что CACHE ON не имеет смысла с технической точки зрения. Это помогает более четко выразить намерение, однако, какие слои фактически должны быть признаны недействительными.

Более гибким решением будет команда, аналогичная RUN которая позволяет некоторому коду оболочки определять, следует ли сделать кеш недействительным. Код выхода 0 может означать «использовать кеш», а 1 - «сделать кеш недействительным». Если код оболочки не указан, по умолчанию можно было бы сделать кеш недействительным с этого момента. Например, команду можно назвать INVALIDATE.

почему это было закрыто без комментариев?

Был комментарий, но он скрыт github
https://github.com/moby/moby/issues/1996#issuecomment -93592837

+1

Эта функция была бы мне сейчас спасением.

+1

Заканчивая это, поскольку мы не видим так много реальных случаев использования

212 комментариев и подсчет, но все еще нет варианта использования? Кажется довольно невежественным.

+1

+1

+1

+1

+1

проблема все еще существует и требует решения. Есть еще множество реальных применений.

+1

Я подозреваю, что у разработчиков Docker нет стимула реализовывать это, чтобы защитить свою централизованную инфраструктуру здания от DDsS-запросов без кеширования.

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

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

@jaromil Это не совсем так, поскольку это также невозможно в репозиториях с собственным хостом.

Какое программное обеспечение существует для запуска собственного репозитория? Я действительно не знаю, о чем вы.
Простым самостоятельным решением может быть cron cloning git repos и runnig docker build --no-cache - я уверен, что эта проблема не может возникнуть в программном обеспечении с открытым исходным кодом: любой может изменить командную строку сборки docker.

@jaromil Не думаю, что проблема в этом. Было бы более эффективно использовать его для проектов DockerHub с открытым исходным кодом (как и для платных, они не взимают плату за количество сборок). В среде CI / CD с частыми сборками это становится еще хуже.

Если вам нужно это сделать (вы используете docker и git и не хотите, чтобы 5 контейнеров работали с общими томами), вы должны перестраивать контейнер и загружать его каждый раз при загрузке новой версии. Весь контейнер.
С флагом отсутствия кеширования в коде каждый раз, когда вы запускаете сборку, вы просто собираете и заменяете этот единственный слой вместо всего контейнера для обновления версии.

Насчет репутации самостоятельного хостинга вы были бы удивлены. Я понимаю комментарий @bluzi , нет никакого влияния

Хорошо, это, безусловно, более сложный сценарий, о котором я мечтал. теперь я думаю ... загрузка с помощью однослойных хэшей без кэша ... push и override, вы называете это. Я не уверена

TL; DR: я думаю, что некоторые улучшения в документации Docker могут очень помочь.

Я оказался здесь после того, как столкнулся с собственными проблемами / путаницей с кешированием. Прочитав все комментарии здесь и на https://github.com/moby/moby/pull/10682, я нашел работоспособное решение для своего конкретного случая использования. Тем не менее, я все еще был разочарован реакцией Докера на это, и, похоже, многие другие думают так же.

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

Читая между строк, мне кажется, что большинство ранних комментаторов этого запроса функции были бы довольны решением, которое использует дополнительные аргументы для docker image build чтобы отключить кеш в определенной точке в Dockerfile. Похоже, что текущего решения Docker для этого (описанного в https://github.com/moby/moby/issues/1996#issuecomment-172606763) должно быть достаточно в большинстве этих случаев, и похоже, что многие пользователи довольны этим . (Если у кого-то есть вариант использования, в котором они могут предоставить дополнительные аргументы для docker image build но это решение все еще неадекватно, вероятно, было бы полезно добавить комментарий, объясняющий, почему это неадекватно.)

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

Снова читая между строк, мне кажется, что все эти варианты использования либо связаны со службами, которые запускают docker image build от имени пользователя, либо связаны с файлами Dockerfiles, которые распространяются среди других пользователей, которые затем запускают docker image build сами. (Если у кого-то есть другие варианты использования, в которых передача дополнительных аргументов в docker image build является проблемой, вероятно, поможет добавить комментарий, подробно объясняющий ваш вариант использования.)

Во многих из этих случаев может показаться, что вариант использования на самом деле не требует возможности отключения кеширования в определенной точке файла Docker (что было исходной точкой этого запроса функции). Вместо этого, похоже, что многие пользователи были бы довольны возможностью полностью отключить кеширование из Dockerfile, без использования аргумента "--no-cache" для docker image build и без необходимости ручного изменения Dockerfile перед каждым строить. (При описании вариантов использования, вероятно, было бы полезно упомянуть, действительно ли требуется частичное кеширование или для вашего варианта использования будет достаточно полного отключения кеша.)

В случаях, когда служба запускает docker image build от имени пользователя, похоже, что Docker ожидает, что все такие службы либо безоговорочно отключат кеш, либо предоставят пользователю возможность отключить кеш. Согласно https://github.com/moby/moby/pull/10682#issuecomment-73777822, Docker Hub безоговорочно отключает кеш. Если служба еще не делает этого, Docker предлагает https://github.com/moby/moby/pull/10682#issuecomment-159255451 пожаловаться поставщику услуг по этому поводу.

Мне кажется, что Docker может занять разумную позицию в отношении сервисов, запускающих docker image build . Однако эта позиция действительно должна быть официально задокументирована на видном месте, чтобы и поставщики услуг, и пользователи знали, чего ожидать. Не похоже, что эта позиция или поведение кэширования Docker Hub в настоящее время документированы где-либо, кроме тех нестандартных комментариев, скрытых глубоко внутри этого огромного / древнего / закрытого запроса на перенос, поэтому неудивительно, что и поставщики услуг, и пользователи обычно поймите это неправильно. Возможно, добавление информации к справочнику docker build описывающее мнение Docker об использовании кеширования службами сборки, и добавление информации в документацию по автоматической сборке Docker Hub о поведении кэширования Docker Hub могло бы устранить эту проблему?

В случаях, когда файлы Docker распространяются среди других пользователей, которые затем сами запускают docker image build , некоторые люди утверждали, что использование простой команды docker build . (без дополнительных аргументов) настолько распространено, что для разработчиков Dockerfile неразумно требовать от пользователей добавления аргументов, в то время как другие люди (например: https://github.com/moby/moby/issues/1996#issuecomment-72238673 https://github.com/moby/moby/pull / 10682 # issuecomment-73820913 https://github.com/moby/moby/pull/10682#issuecomment-73992301) утверждали, что было бы неуместно безоговорочно запрещать пользователям использовать кеширование путем жесткого кодирования переопределений кеша в Dockerfile. Из-за отсутствия подробных / убедительных примеров использования для этого Docker принял исполнительное решение потребовать дополнительные аргументы командной строки для управления кешированием, что, по-видимому, является источником большей части сохраняющегося разочарования. (Если у кого-то есть убедительный пример использования, связанный с этим, вероятно, было бы полезно добавить комментарий, объясняющий это подробно.)

Однако мне кажется, что Docker может сделать всех счастливыми, просто нарушив привычку пользователей запускать docker build . без дополнительных аргументов. Поведение кэширования и аргумент «--no-cache» не упоминаются ни в одном из соответствующих руководств по Docker (например, this или this
или это ). Вдобавок, хотя документация docker build действительно перечисляет аргумент «--no-cache», она не объясняет его значение и не подчеркивает тот факт, что он важен во многих распространенных случаях использования. (Также обратите внимание, что документация docker image build пуста. Она должна, по крайней мере, ссылаться на документацию docker build .) Похоже, что только справочник по документация по передовым методам на самом деле описывают поведение кэширования и упоминают роль аргумента --no-cache. Однако эти документы, вероятно, будут прочитаны только опытными разработчиками Dockerfile. Поэтому неудивительно, что только продвинутые пользователи знакомы с аргументом «--no-cache», и что большинство пользователей когда-либо запускали docker build . без дополнительных аргументов, а затем были сбиты с толку, когда он не работал. как они или автор Dockerfile ожидают / хотят. Возможно, обновление руководств и документации docker build чтобы упомянуть аргумент «--no-cache» и его значение, могло бы устранить эту проблему?

+1

+1

Официальный инструмент docker bashbrew не позволяет добавлять аргументы при создании образов, поэтому "официально поддерживаемый" ответ не работает.

+1

+1

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

Я попытался обойти это, используя ARG в сценарии, который получает COPY до указания ARG, но Docker, похоже, аннулирует все после объявления ARG, если вход ARG изменился.

Поведение, которое я хотел бы видеть, - это иметь возможность помечать ARG как всегда кэшируемое либо в Dockerfile, либо в CLI при вызове build. Для таких случаев использования, как секреты, это часто то, что вам нужно; Содержание списка пакетов должно указывать, когда кеш становится недействительным, а не аргумент, переданный в ARG.

Я понимаю теорию, согласно которой эти разделы можно вытащить во второе изображение, которое затем будет использоваться в качестве базового изображения, но это довольно неудобно, когда пакеты используются проектом, например, в package.json, requirements.txt, Gemfile и т. Д. Этот базовый образ тоже будет постоянно перестраиваться.

+1 к CACHE OFF из этой строковой директивы - я ждал этого буквально годы.

Мне пришлось отключить кеш в Docker Hub / Docker Cloud, и это сэкономило бы массу времени и сборок, если бы я мог кэшировать большой слой, а затем просто запустить команду обновления nocache в конце файла dockerfile.

Поведение, которое я хотел бы видеть, - это иметь возможность помечать ARG как всегда кэшируемое либо в Dockerfile, либо в CLI при вызове build. Для таких случаев использования, как секреты, это часто то, что вам нужно; Содержание списка пакетов должно указывать, когда кеш становится недействительным, а не аргумент, переданный в ARG.

--build-arg PASSWORD=<wrong> может привести к другому результату, чем --build-arg PASSWORD=<correct> , поэтому я не уверен, подойдет ли для этого простой просмотр содержимого списка пакетов. Построитель не может сам предвидеть, какое влияние установка / изменение переменной среды окажет на выполняемые шаги (являются ли make DEBUG=1 foo и make DEBUG=0 foo одинаковыми?). Единственное исключение в настоящее время сделано для переменных среды xx_PROXY , где предполагается, что прокси может потребоваться для сетевых подключений, но переключение на другой прокси должно дать тот же результат. Поэтому для того, чтобы это сработало, потребуется какой-то способ указать конкретную переменную среды (/ build arg), которую нужно игнорировать для кеширования.

обратите внимание, что BuildKit теперь имеет экспериментальную поддержку для RUN --mount=type=secret и RUN --mount=type=ssh , которые могут быть полезны для передачи секретов / учетных данных, но могут по-прежнему аннулировать кеш, если эти секреты изменяются (не уверен; это может быть вызвать в системе отслеживания проблем buildkit https://github.com/moby/buildkit/issues).

Мне пришлось отключить кеш в Docker Hub / Docker Cloud

Действительно ли Docker Hub / Cloud _использует_ кеширование? Я думаю, что там не используется кеширование (например, используется эфемерная среда сборки)

Я помню, что DockerHub раньше не использовал кеширование сборки, но я просматривал свои автоматизированные сборки в Docker Cloud непосредственно перед этим тикетом, и теперь рядом с ползунком Autobuild каждой ветки есть ползунок Building Caching, хотя по умолчанию он отключен.

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

Я бы предпочел, чтобы начальный git clone && make build был кэширован, а затем просто сделал NO CACHE на шаге git pull && make build чтобы получить только гораздо меньшее обновление кода + зависимости, которые еще не установлены в качестве последнего Layer, тем самым эффективно кэшируя основную часть изображения не только для сборок, но, что более важно, для всех клиентов, которым сейчас необходимо повторно загружать и заменять сотни МБ слоев каждый раз, что крайне неэффективно.

Размер обусловлен тем, что многие проекты имеют большое количество зависимостей, например. системные пакеты + модули Perl CPAN + модули Python PyPI и т. д.

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

Кэширование более ранних уровней, которые включают все системные пакеты + модули CPAN + PyPI, будет означать, что очень мало должно измениться на последнем уровне обновлений, поскольку в большинстве случаев я не буду обновлять рабочие установленные модули (я использовал сценарии из моих bash-tools репозиторий подмодуля служебной программы для установки только пакетов, которые еще не установлены, чтобы избежать установки ненужных обновлений, не связанных с исправлениями ошибок)

Некоторое время я искал уловку вроде изменения ARG (идея пришла мне в голову при поиске по блогам вроде http://dev.im-bot.com/docker-select-caching/):

В Dockerfile:

ARG NOCACHE=0

Затем запустите docker build так:

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

но я не думаю, что это возможно в Docker Cloud.

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

@thaJeztah Да, такое поведение может легко иметь негативные последствия, если его неправильно

--build-arg PASSWORD=<wrong> может привести к другому результату, чем --build-arg PASSWORD=<correct> , поэтому я не уверен, что простой просмотр содержимого списка пакетов сработает для этого.

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

Да, я представлял себе что-то вроде docker build --force-cache-build-arg SECRET=supersecret . Это довольно неуклюже, я уверен, что кто-то может придумать что-нибудь получше.

@HariSekhon Похоже, ваш вариант использования на самом деле противоположен моему, правда? Вы хотите , чтобы выборочно силы промаха кэша, а не выборочно силой ударил кэш?

Добавление этого сработало для меня:

ADD http://date.jsontest.com/ /tmp/bustcache

но этот сайт сейчас не работает. Это должно работать

ADD http://api.geonames.org/timezoneJSON?formatted=true&lat=47.01&lng=10.2&username=demo&style=full /tmp/bustcache

@itdependsnetworks

Отлично, это хороший обходной путь, и теперь сайт готов. Также полезно записать дату сборки образа.

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

COPY /dev/random ...

но это не сработало, хотя RUN ls -l -R /etc показало, что такие файлы присутствуют, они всегда не найдены, я подозреваю, что есть некоторая защита от использования специальных файлов.

Теперь я думаю больше об этом в DockerHub / Docker Cloud, вы, вероятно, также можете использовать обработчик предварительной сборки, чтобы сгенерировать файл, содержащий отметку даты, а затем скопировать его в изображение непосредственно перед слоем, который вы хотите удалить из кеша, достигнув аналогичного результата, хотя ADD показанный выше, я думаю, более переносим на локальные докеры и облачные сборки.

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

Первый постоянно нарушает дневную квоту, а второй теперь выдает эту ошибку.

{"status": {
  "message": "the daily limit of 20000 credits for demo has been exceeded. Please use an application specific account. Do not use the demo account for your application.",
  "value": 18
}}

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

Пример использования:

FROM something
... 
CACHE_BUST git ls-remote my-git-repo HEAD
RUN git clone --depth=1 my-git-repo ...
...
CMD ["my-cmd"]

Команда в приведенной выше инструкции CACHE_BUST выведет SHA из HEAD указанного репо, таким образом мой файл докеров может узнать, клонировать или нет, на основе изменений в репо.

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

Мой текущий рабочий процесс будет выглядеть так:

ARG SHA_TO_BUILD
RUN echo SHA_TO_BUILD
RUN git clone ...
...everything else reliant on that clone
$> ./build-my-image.sh $(get-latest-sha)

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

такая замечательная функция, почему все еще ожидается?

Другой вариант использования - когда содержимое файла изменяется, а Dockerfile - нет.

Например, если у меня есть COPY file.txt . и я изменяю file.txt Docker все равно будет использовать кешированную старую версию.

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

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

@brennancheung, если это так, то это ошибка. Не стесняйтесь открывать отдельную проблему с воспроизводимыми шагами.

Думаю, главное в том, что @brennancheung
https://github.com/brennancheung говорит, что, например, когда вы
загрузка файла конфигурации (или чего-то подобного). Вам не нужно
переустановите все приложение, просто обновите эти файлы и команды
связанный с ним, запускаем докер и вуаля, система настроена.
Конечно, часто вы можете просто поместить файл конфигурации ближе к концу
ваш стек, но это не всегда так.

Am Mi., 20. März 2019 um 00:10 Uhr schrieb Tibor Vass <
[email protected]>:

@brennancheung https://github.com/brennancheung, если это так,
это ошибка. Не стесняйтесь открывать отдельную проблему с воспроизводимыми шагами.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/1996#issuecomment-474666893 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/ALBon0edO9m5BU3C5Ik2i__9eogZc1Jiks5vYaaNgaJpZM4BB_sR
.

-
Тьяго Родригес

Пробовал это https://github.com/moby/moby/issues/1996#issuecomment -185872769

Но это влияет только на кеш во время / после первого использования, а не только на его определение.

https://docs.docker.com/engine/reference/builder/#impact -on-build-caching

Если Dockerfile определяет переменную ARG, значение которой отличается от предыдущей сборки, то «промах в кеше» происходит при ее первом использовании, а не при ее определении.

@samstav "первое использование" стоит первый RUN после ARG (если этот ARG находится на этапе сборки), поэтому:

ARG FOO=bar

FROM something
RUN echo "this won't be affected if the value of FOO changes"
ARG FOO
RUN echo "this step will be executed again if the value of FOO changes"

FROM something-else
RUN echo "this won't be affected because this stage doesn't use the FOO build-arg"

Вышеупомянутое немного зависит от того, используете ли вы построитель следующего поколения (BuildKit), поэтому с включенным DOCKER_BUILDKIT=1 , потому что BuildKit может пропускать этапы сборки, если они не нужны для последней стадии (или пропускать этапы сборки если их можно полностью кэшировать)

Была ли эта страница полезной?
0 / 5 - 0 рейтинги