Как обойти измененный слой и перейти к кэшу более позднего слоя

#docker

#докер #docker

Вопрос:

У меня есть dockerfile со многими слоями. Я создаю изображения до уровня n , где сборка завершается неудачей. Затем я что-то меняю в коде таким образом, чтобы это исправило проблему сборки layer n . Я знаю эту кодовую базу, и я знаю, что это конкретное изменение не имеет никакого значения для функциональности layer n-m , но этот слой перестраивается, потому что он основан на этой кодовой базе. Я хотел бы избежать этой перестройки, а вместо этого перейти к кешу слоя n-1 и продолжить сборку оттуда. Возможно ли это?

Если я это сделаю docker build --cache-from IMAGE_ID_OF_LAYER_n_1 , похоже, что --cache-from будет проигнорировано, и сборка начнется со слоя n-m .

Ответ №1:

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

Например, если у вас есть

 FROM some/base         # 00000000
RUN step-l             # 11111111
RUN step-m --option-a  # 22222222
RUN step-n             # 33333333
  

затем для последней строки кэшируется «изображение 22222222 плюс RUN step-n , создающее изображение 33333333″. Но если вы затем измените

 FROM some/base         # 00000000
RUN step-l             # 11111111
RUN step-m --option-b  # 44444444
RUN step-n
  

тогда в кэше ничего нет для «изображения 44444444, плюс RUN step-n «.

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

 FROM some/base AS build-m
RUN step-m --option-a

FROM some/base AS build-n
RUN step-n

FROM some/base
COPY --from=build-m /opt/m /opt/m
COPY --from=build-n /opt/n /opt/n
  

Тогда, даже если вы измените RUN step-m , RUN step-n все равно можно будет кэшировать. Окончательную сборку все равно придется повторить, но это просто копирование файлов. (Представьте себе установку, в которой выполняется один шаг webpack для предварительной компиляции приложения браузера, и вам просто нужно скопировать его dist дерево, например.)