Docker, wie man die Pip-Anforderungen.txt nur ausführt, wenn es eine Änderung gab?

90

In einer Docker-Datei habe ich eine Ebene, die installiert requirements.txt:

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

Wenn ich das Docker-Image erstelle, wird der gesamte Prozess ausgeführt, unabhängig von Änderungen, die an dieser Datei vorgenommen wurden.

Wie stelle ich sicher, dass Docker nur ausgeführt wird, pip install -r requirements.txtwenn eine Änderung an der Datei vorgenommen wurde?

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))
Prometheus
quelle
1
Bitte posten Sie die Ausgabe von docker build(und Ihrer Dockerfile). Vermutlich ist es ein früherer Schritt in Ihrem Erstellungsprozess, der den Cache sprengt und dazu führt, dass dieser Schritt ausgeführt wird.
Thomas Orozco
Update OP mit allem, was ich im Moment habe
Prometheus
1
Nur dieser Schritt ist nicht sinnvoll. Bitte posten Sie die vollständige Ausgabe (oder zumindest die Docker-Datei).
Thomas Orozco

Antworten:

171

Ich gehe davon aus, dass Sie irgendwann in Ihrem Erstellungsprozess Ihre gesamte Anwendung mit COPYoder in das Docker-Image kopieren ADD:

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

Das Problem ist, dass Sie den Docker-Build-Cache jedes Mal ungültig machen, wenn Sie die gesamte Anwendung in das Image kopieren. Dadurch wird auch der Cache für alle nachfolgenden Erstellungsschritte ungültig.

Um dies zu verhindern, würde ich empfehlen, nur dierequirements.txt Datei in einem separaten Erstellungsschritt zu kopieren , bevor die gesamte Anwendung zum Image hinzugefügt wird:

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

Da sich die Anforderungsdatei selbst wahrscheinlich nur selten ändert, können Sie die zwischengespeicherten Ebenen bis zu dem Punkt verwenden, an dem Sie Ihren Anwendungscode zum Bild hinzufügen.

Helmbert
quelle
8
Als allgemeine Richtlinie halte ich COPYes für vorzuziehen, es ADDsei denn, Sie benötigen ausdrücklich das Verhalten von ADD.
Metropolis
2
@ Metropolis, du bist völlig richtig. Danke für den Tipp.
Helmbert
5
Stimmen Sie mit @Metropolis überein. ADDwird nur benötigt, wenn der <src>Ordner ein Archiv enthält, das entpackt werden muss oder die Remote-URL-Behandlung unterstützen muss. {Quellcode}
Mohsin
43

Dies wird direkt in Dockers eigenen " Best Practices zum Schreiben von Docker- Dateien " erwähnt:

Wenn Sie mehrere Dockerfile-Schritte haben, die unterschiedliche Dateien aus Ihrem Kontext verwenden, KOPIEREN Sie diese einzeln und nicht alle gleichzeitig. Dadurch wird sichergestellt, dass der Build-Cache jedes Schritts nur ungültig wird (wodurch der Schritt erneut ausgeführt werden muss), wenn sich die speziell erforderlichen Dateien ändern.

Zum Beispiel:

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

Dies führt zu weniger Cache-Ungültigmachungen für den RUN-Schritt als beim Einfügen von COPY. / tmp / davor.

jrc
quelle
0

Alternativ können Sie als schnelleres Mittel zum Ausführen der Datei "require.txt" ohne Eingabe von "yes" zur Bestätigung der Installation von Bibliotheken Folgendes neu schreiben:

COPY requirements.txt ./
RUN pip install -y -r requirements.txt
COPY ./"dir"/* .
Asante Michael
quelle