Сборка Docker не использует кеш при копировании Gemfile при использовании --cache-from - PullRequest
0 голосов
/ 07 февраля 2019

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

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

docker pull $CONTAINER_IMAGE:latest

docker build --cache-from $CONTAINER_IMAGE:latest \
             --tag $CONTAINER_IMAGE:$CI_COMMIT_SHORT_SHA \
             .

Из результатов сборки мы можем увидетьCOPY Gemfile не использует регистр из образа latest, хотя я не обновил этот файл:

Step 15/22 : RUN gem install bundler -v 1.17.3 &&     ln -s /usr/local/lib/ruby/gems/2.2.0/gems/bundler-1.16.0 /usr/local/lib/ruby/gems/2.2.0/gems/bundler-1.16.1
 ---> Using cache
 ---> 47a9ad7747c6
Step 16/22 : ENV BUNDLE_GEMFILE=$APP_HOME/Gemfile     BUNDLE_JOBS=8
 ---> Using cache
 ---> 1124ad337b98
Step 17/22 : WORKDIR $APP_HOME
 ---> Using cache
 ---> 9cd742111641
Step 18/22 : COPY Gemfile $APP_HOME/
 ---> f7ff0ee82ba2
Step 19/22 : COPY Gemfile.lock $APP_HOME/
 ---> c963b4c4617f
Step 20/22 : RUN bundle install
 ---> Running in 3d2cdf999972

В стороне узла : он работаетотлично на моем локальном компьютере.

Просмотр документации Docker Использование кэша сборки , кажется, не объясняет поведение здесь, поскольку ни Dockerfile, ни Gemfile не изменились, поэтому кэш должен

Что может заставить Docker не использовать кеш для Gemfile?

Обновление

Я попытался скопировать файлы с правильными разрешениями, используя COPY --chown=user:group source dest, но этодо сих пор не использует кеш.

Открыт DockeТема форума: https://forums.docker.com/t/docker-build-not-using-cache-when-copying-gemfile-while-using-cache-from/69186

Ответы [ 2 ]

0 голосов
/ 07 мая 2019

В последние несколько дней я ломал голову над проблемами со сборкой Docker и --cache-from, и это немного расстраивает отсутствие документации для правильного поведения --cache-from, хотя есть некоторая дезинформация вwild.

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

При предоставлении нескольких --cache-from порядок имеет значение!

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

Это объясняет тот, кто реализовал эту функцию в Github PR :

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

В первоначальном предложении о покупке билетов также есть более длинное объяснение :

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

Использование --cache-from является исключительным: локальный кэш Docker не будет использоваться

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

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

  1. предоставить правильный тег с --cache-from (и с правильным приоритетом);или

  2. вообще не использовать --cache-from (так что будет использоваться локальный кеш сборки)

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

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

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

0 голосов
/ 14 февраля 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...