Почему docker перестраивает все слои каждый раз, когда я меняю аргументы сборки - PullRequest
0 голосов
/ 07 марта 2020

У меня есть файл docker, в котором много слоев. В верхней части файла у меня есть несколько аргументов, таких как

FROM ubuntu:18.04

ARGS USER=test-user
ARGS UID=1000
#ARGS PW=test-user

# Then several Layers which does not use any ARGS. Example
LABEL version="1.0"

ENV LANG=C.UTF-8 LC_ALL=C.UTF-8

RUN mkdir ~/mapped-volume

RUN apt-get update && apt-get install -y wget bzip2 ca-certificates build-essential curl git-core htop pkg-config unzip unrar tree freetds-dev vim \
sudo nodejs npm net-tools flex perl automake bison libtool byacc

# And so on 
# And finally towards the end
# Setup User
RUN useradd -m -d /home/${USER} --uid ${UID} -G sudo -s /bin/bash ${USER} 
# && echo "${USER}:${PW}" | chpasswd

# Couple of  more commands to change dir, entry point etc. Example

Когда я создаю этот файл docker с любым значением аргумента, отличным от последней сборки, и / или после небольших изменений в последних двух слоях, build снова все строит. Он не использует кэшированный слой. Команда, которую я использую для сборки, выглядит примерно так:

docker build --build-arg USER=new-user --build-arg UID=$UID -t my-image:1.0 .

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

UID -t my-image:1.0 .
Sending build context to Docker daemon  44.54kB
Step 1/23 : FROM ubuntu:18.04
 ---> ccc6e87d482b
Step 2/23 : ARG USER=ml-user
 ---> Using cache
 ---> 6c0c5d5c5056
Step 3/23 : ARG UID=1000
 ---> Using cache
 ---> b25867c282c7
Step 4/23 : LABEL version="1.0"
 ---> Running in 1ffff70d56c1
Removing intermediate container 1ffff70d56c1
 ---> 0f1277def3ca
Step 5/23 : ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
 ---> Running in 49d08c41b233
Removing intermediate container 49d08c41b233
 ---> f5b345573c1f
Step 6/23 : RUN mkdir ~/mapped-volume
 ---> Running in e4f8a5956450
Removing intermediate container e4f8a5956450
 ---> 1b22731d9051
Step 7/23 : RUN apt-get update && apt-get install -y wget bzip2 ca-certificates build-essential curl git-core htop pkg-config unzip unrar tree freetds-dev vim sudo nodejs npm net-tools flex perl automake bison libtool byacc
 ---> Running in ffc297de6234
Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]

Итак, начиная с шага 7, он продолжает выполнять все шаги без использования кеша того слоя, в котором должно быть множество пакетов. Почему? Как я могу это остановить? Раньше, когда у меня не было аргументов, этот слой и другие слои использовались для извлечения из кэша.

1 Ответ

2 голосов
/ 08 марта 2020

Переместите свои арги прямо перед тем, как они понадобятся. Docker не заменяет аргументы в командах RUN перед их выполнением. Вместо этого аргументы передаются как переменные среды и расширяются оболочкой во временном контейнере. Из-за этого изменение аргумента arg является изменением среды и отсутствием кэша сборки для этого шага. Как только один шаг пропускает кеш, все последующие шаги должны быть перестроены.

FROM ubuntu:18.04

# Then several Layers which does not use any ARGS. Example

ENV LANG=C.UTF-8 LC_ALL=C.UTF-8

RUN mkdir ~/mapped-volume

RUN apt-get update && apt-get install -y wget bzip2 ca-certificates build-essential curl git-core htop pkg-config unzip unrar tree freetds-dev vim \
sudo nodejs npm net-tools flex perl automake bison libtool byacc

# And so on 
# And finally towards the end
# Setup User
ARGS USER=test-user
ARGS UID=1000
RUN useradd -m -d /home/${USER} --uid ${UID} -G sudo -s /bin/bash ${USER} 
# && echo "${USER}:${PW}" | chpasswd

# Couple of  more commands to change dir, entry point etc. Example

LABEL version="1.0"

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

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