Докер, как запустить pip requirements.txt, только если было изменение?

98

В Dockerfile у меня есть слой, который устанавливает requirements.txt:

FROM python:2.7
RUN pip install -r requirements.txt

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

Как сделать так, чтобы Docker запускался только в том pip install -r requirements.txtслучае, если в файл были внесены изменения?

Removing intermediate container f98c845d0f05
Step 3 : RUN pip install -r requirements.txt
 ---> Running in 8ceb63abaef6
Collecting https://github.com/tomchristie/django-rest-framework/archive/master.zip (from -r requirements.txt (line 30))
  Downloading https://github.com/tomchristie/django-rest-framework/archive/master.zip
Collecting Django==1.8.7 (from -r requirements.txt (line 1))
Прометей
источник
1
Пожалуйста, опубликуйте вывод docker build(и свой Dockerfile). Предположительно, это более ранний шаг в процессе сборки, который разрушает кеш, вызывая выполнение этого шага.
Томас Ороско
обновить OP со всем, что у меня есть на данный момент
Prometheus
1
Просто этот шаг бесполезен. Пожалуйста, опубликуйте полный вывод (или хотя бы Dockerfile).
Томас Ороско

Ответы:

179

Я предполагаю, что в какой-то момент процесса сборки вы копируете все свое приложение в образ Docker с помощью COPYили ADD:

COPY . /opt/app
WORKDIR /opt/app
RUN pip install -r requirements.txt

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

Чтобы этого не произошлоrequirements.txt , я бы предложил скопировать только файл на отдельном этапе сборки перед добавлением всего приложения в образ:

COPY requirements.txt /opt/app/requirements.txt
WORKDIR /opt/app
RUN pip install -r requirements.txt
COPY . /opt/app
# continue as before...

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

Helmbert
источник
8
В качестве общего правила я считаю, COPYчто предпочтительнее, ADDесли вам не требуется поведение ADD.
Метрополис
2
@Metropolis, вы совершенно правы. Спасибо за подсказку.
Helmbert
5
Согласитесь с @Metropolis. ADDтребуется только в том случае, если <src>папка содержит архив, который необходимо распаковать или поддерживать удаленную обработку URL. {исходный код}
Mohsin
45

Это прямо упоминается в собственных « лучших практиках написания файлов Docker »:

Если у вас есть несколько шагов Dockerfile, которые используют разные файлы из вашего контекста, КОПИРУЙТЕ их по отдельности, а не все сразу. Это гарантирует, что кеш сборки каждого шага будет признан недействительным (принудительный повторный запуск шага) только в случае изменения специально требуемых файлов.

Например:

COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/

Приводит к меньшему количеству недействительности кеша для шага RUN, чем если бы вы поместили COPY. / tmp / перед ним.

jrc
источник
0

В качестве альтернативы более быстрому способу запуска файла requirements.txt без ввода «да» для подтверждения установки библиотек вы можете переписать его как:

COPY requirements.txt ./
RUN pip install -y -r requirements.txt
COPY ./"dir"/* .
Асанте Майкл
источник