Docker, jak uruchomić pip Require.txt tylko w przypadku zmiany?

91

W pliku Dockerfile mam warstwę, która instaluje requirements.txt :

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

Kiedy buduję obraz dockera, uruchamia cały proces niezależnie od zmian wprowadzonych w tym pliku.

Jak się upewnić, że Docker działa tylko pip install -r requirements.txtwtedy, gdy nastąpiła zmiana w pliku?

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))
Prometeusz
źródło
1
Opublikuj wyjście docker build(i swoje Dockerfile). Przypuszczalnie jest to wcześniejszy krok w procesie kompilacji, który zrywa pamięć podręczną, powodując uruchomienie tego kroku.
Thomas Orozco,
zaktualizuj OP ze wszystkim, co mam w tej chwili
Prometheus
1
Tylko ten krok nie jest przydatny. Proszę pisać na pełną moc (lub przynajmniej Dockerfile).
Thomas Orozco,

Odpowiedzi:

171

Zakładam, że w pewnym momencie procesu kompilacji kopiujesz całą aplikację do obrazu platformy Docker za pomocą COPYlub ADD:

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

Problem polega na tym, że za każdym razem, gdy kopiujesz całą aplikację do obrazu, unieważniasz pamięć podręczną kompilacji platformy Docker. Spowoduje to również unieważnienie pamięci podręcznej dla wszystkich kolejnych kroków kompilacji.

Aby temu zapobiec, sugerowałbym skopiowanie tylkorequirements.txt pliku w oddzielnym kroku kompilacji przed dodaniem całej aplikacji do obrazu:

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

Ponieważ sam plik wymagań prawdopodobnie zmienia się rzadko, będziesz mógł używać warstw z pamięci podręcznej do momentu dodania kodu aplikacji do obrazu.

Helmbert
źródło
8
Uważam, że ogólna wskazówka COPYjest preferowana, ADDchyba że wyraźnie potrzebujesz zachowania ADD.
Metropolis
2
@Metropolis, masz całkowitą rację. Dzięki za podpowiedź.
helmbert
5
Zgadzam się z @Metropolis. ADDjest potrzebny tylko wtedy, gdy <src>folder zawiera archiwum, które musi zostać rozpakowane lub musi obsługiwać zdalną obsługę adresów URL. {kod źródłowy}
Mohsin,
44

Jest to bezpośrednio wspomniane we własnych „ Najlepszych praktykach dotyczących pisania Dockerfiles ”:

Jeśli masz wiele kroków Dockerfile, które używają różnych plików z twojego kontekstu, KOPIUJ je indywidualnie, a nie wszystkie naraz. Zapewni to, że pamięć podręczna kompilacji każdego kroku zostanie unieważniona (wymuszając ponowne uruchomienie kroku) tylko wtedy, gdy zmienią się konkretnie wymagane pliki.

Na przykład:

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

Skutkuje mniejszą liczbą unieważnień pamięci podręcznej dla kroku RUN, niż w przypadku umieszczenia COPY. / tmp / przed nim.

jrc
źródło
0

Alternatywnie, aby przyspieszyć uruchomienie pliku Requirements.txt bez wpisywania „tak” w celu potwierdzenia instalacji bibliotek, możesz ponownie napisać jako:

COPY requirements.txt ./
RUN pip install -y -r requirements.txt
COPY ./"dir"/* .
Asante Michael
źródło