Когда вызов «RUN ln» может быть кэширован Docker?

#docker

#docker

Вопрос:

У меня есть следующий результат от docker build . . Почему Docker, похоже, никогда не кэширует шаг 4? Могу ли я заставить его использовать кеш с некоторой настройкой?

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

   docker build .


Sending build context to Docker daemon  3.678MB

Step 1/36 : FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder
 ---> c4155a9104a8

Step 2/36 : ARG branch_build_commit
 ---> Using cache
 ---> 2a8f43280a27

Step 3/36 : WORKDIR /tmp
 ---> Using cache
 ---> f3bf42ec98ab

Step 4/36 : RUN ln -snf /usr/share/zoneinfo/America/Chicago /etc/localtime amp;amp; echo America/Chicago > /etc/timezone
 ---> Running in 32bd1e2cff9e
Removing intermediate container 32bd1e2cff9e
 ---> 8d49354c0de6
  

Ответ №1:

В документации Dockerfile отмечается, что под влиянием [аргумента] на кэширование сборки:

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

Если это происходит в контексте системы CI и каждой сборке обычно передается docker build --build-arg branch_build_commit=$(git rev-parse HEAD) . или что-то подобное, тогда каждая сборка будет иметь другое ARG значение, и RUN инструкции всегда будут вызывать промах кэша.

С другой стороны, это просто соглашение, которое ARG появляется в начале файла Dockerfile, чтобы его можно было найти. Документация Dockerfile по области действия [аргумента] содержит некоторые конкретные примечания о том, что ARG значения могут использоваться только после ARG инструкции, и имеет пример того, что ARG значения не являются первыми. Таким образом, вы можете снова запустить кэширование, переместив ARG инструкцию позже в файл:

 FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as builder
# These statements don't use the ARG value so they can come first.
WORKDIR /tmp
RUN ln -snf /usr/share/zoneinfo/America/Chicago /etc/localtime amp;amp; echo America/Chicago > /etc/timezone
# Then you can declare the ARG value later
ARG branch_build_commit
# And any uses must come after the ARG statement.
RUN echo ${branch_build_commit:-unknown} > /etc/build-version