Deaktivieren Sie den Cache für bestimmte RUN-Befehle


98

Ich habe einige RUNBefehle in meiner Docker-Datei, die ich -no-cachejedes Mal ausführen möchte, wenn ich ein Docker-Image erstelle.

Ich verstehe, dass das docker build --no-cacheCaching für die gesamte Docker-Datei deaktiviert wird.

Ist es möglich, den Cache für einen bestimmten RUN-Befehl zu deaktivieren?


1
Wenn Sie den Cache für einen einzelnen Befehl deaktivieren und das Ergebnis nicht mit dem zwischengespeicherten Lauf übereinstimmt, müssen Sie alle verbleibenden Schritte neu erstellen. Ist das Ihr Ziel oder hoffen Sie, nur eine einzige Ebene neu zu erstellen und diese irgendwie in den Speicherort der zuvor zwischengespeicherten Daten einzufügen?
BMitch

2
Ich hatte gehofft, bestimmte Ebenen neu erstellen zu können, zum Beispiel einen "git pull" -Befehl. Im Moment wird der Befehl "git pull" zwischengespeichert, obwohl das Repo aktualisiert wird.
Vingtoft

2
Es ist leicht genug, einen Zug zu erzwingen, indem man ein nicht verwendetes Argument übergibt. Das Ergebnis der Neuerstellung dieses zwischengespeicherten Eintrags ist jedoch, dass alle folgenden Ebenen neu erstellt werden müssen. Ein Beispiel finden Sie in meiner Antwort hier .
BMitch

Wenn Sie versuchen , den Cache ungültig zu machen, wenn sich eine Git-Fernbedienung geändert hat, sehen Sie sich Folgendes an: So verhindern Sie, dass Dockerfile den Git-Klon zwischenspeichert . Alle Gutschriften an @anq für die verknüpfte Antwort.
HPGMiskin

Antworten:


79

Es gibt immer die Möglichkeit, einen bedeutungslosen und kostengünstig auszuführenden Befehl vor der Region einzufügen, für die Sie den Cache deaktivieren möchten.

Wie in diesem Problemkommentar vorgeschlagen , kann ein Build-Argumentblock hinzugefügt werden (Name kann beliebig sein):

ARG CACHEBUST=1 

vor einem solchen Bereich, und ändern Sie seinen Wert bei jedem Lauf, indem Sie ihn --build-arg CACHEBUST=$(date +%s)als docker buildArgument hinzufügen (der Wert kann auch beliebig sein, hier ist es die aktuelle Datums- und Uhrzeitangabe, um seine Eindeutigkeit über die Läufe hinweg sicherzustellen).

Dadurch wird natürlich auch der Cache für alle folgenden Blöcke deaktiviert, da die Hash-Summe des Zwischenbilds unterschiedlich ist. Dies macht das Deaktivieren des wirklich selektiven Caches zu einem nicht trivialen Problem, wenn man berücksichtigt, wie Docker derzeit funktioniert.


1
Nicht mehr zu funktionieren scheint, gerade ---> Using cacheunter meinem `` ARG CACHEBUST = 1 'Linie ... (und ja , ich habe zu tun --build-arg CACHEBUST=$(date +%s)in meinem Docker - Befehl)
Pylinux

Funktioniert auch bei mir nicht, vielleicht ist es plattformabhängig. Ich hätte erwartet, dass jede ARG-Änderung den Cache ungültig macht.
Oliver

6
Sie müssen hinzufügen, RUN echo "$CACHEBUST"da nur die Verwendung ARGden Cache nicht ungültig macht
Sidharth V

Diese Antwort hat mein Problem hier gelöst: stackoverflow.com/questions/63709147/…
shapeiro yaacov

24

Verwenden

ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache

vor der RUN-Zeile möchten Sie immer ausführen. Dies funktioniert, da ADD immer die Datei / URL abruft und die obige URL bei jeder Anforderung zufällige Daten generiert. Docker vergleicht dann das Ergebnis, um festzustellen, ob der Cache verwendet werden kann.

Ich habe dies auch getestet und funktioniert gut, da es keine zusätzlichen Docker-Befehlszeilenargumente erfordert und auch aus einer Docker-compose.yaml-Datei funktioniert :)


2
Was passiert, wenn random.org beschließt, diesen Endpunkt zu ändern? Wie würden Sie dieses Verhalten kontrollieren?
Andres Leon Rangel

@AndresLeonRangel Zugegeben, dies ist keine Docker-Funktion, sondern eine Art Hack mit Docker-Syntax und bekanntem Webdienst, der seit über 20 Jahren verfügbar ist. Sie können jedoch zu Recht sagen, dass sie diesen Endpunkt möglicherweise verwerfen, wenn sie sich ihre Dokumente jetzt ansehen Ich kann nicht einmal den "Randbyte" -Endpunkt finden und sie haben eine neue API, die sich derzeit in der Beta befindet. Sie können entweder 1) diesen Endpunkt weiter verwenden, bis er fehlschlägt, 2) den neuen Endpunkt verwenden (bis er fehlschlägt) oder 3) Ihren eigenen zufälligen Endpunkt schreiben. In diesem Fall haben Sie die volle Kontrolle :)
Steve

2
Dies ist einige Male fehlgeschlagen ... wenn die Seite nicht erreichbar ist !!! Ich denke, es ist keine perfekte Lösung dafür. ADD fehlgeschlagen: Fehler beim Abrufen von random.org/cgi-bin/randbyte?nbytes=10&format=h mit dem Status 503 Dienst nicht verfügbar: <! DOCTYPE HTML>
Kathi

1
random.org hat DDOS-Schutz hinzugefügt, der diese Lösung jetzt bricht
Brad Root

Es funktioniert nicht und Addess gibt 503 zurück. Wenn Sie Ihre Pipelines nicht blockieren möchten, verwenden Sie diese Lösung nicht
OlegI

8

Nicht direkt, aber Sie können Ihre Docker-Datei in mehrere Teile teilen, ein Image erstellen und dann aus diesem Bild am Anfang der nächsten Docker-Datei das Image mit oder ohne Caching erstellen


1
Ermöglicht dies die Aktualisierung der festgeschriebenen Ebenen im Basis-Docker-Image?
user_mda


3

Die Funktion wurde vor einer Woche hinzugefügt.

ARG FOO=bar

FROM something
RUN echo "this won't be affected if the value of FOO changes"
ARG FOO
RUN echo "this step will be executed again if the value of FOO changes"

FROM something-else
RUN echo "this won't be affected because this stage doesn't use the FOO build-arg"

https://github.com/moby/moby/issues/1996#issuecomment-550020843


0

Ich glaube, dass dies eine leichte Verbesserung gegenüber der obigen Antwort von @ steve ist:

RUN git clone https://sdk.ghwl;erjnv;wekrv;qlk@gitlab.com/your_name/your_repository.git

WORKDIR your_repository

# Calls for a random number to break the cahing of the git clone
# (/programming/35134713/disable-cache-for-specific-run-commands/58801213#58801213)
ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
RUN git pull

Dies verwendet den Docker-Cache des Git-Klons, führt dann jedoch eine nicht zwischengespeicherte Aktualisierung des Repositorys aus.

Es scheint zu funktionieren und ist schneller - aber vielen Dank an @steve für die Bereitstellung der zugrunde liegenden Prinzipien.


-2

Ein weiterer schneller Hack besteht darin, einige zufällige Bytes vor Ihrem Befehl zu schreiben

RUN head -c 5 /dev/random > random_bytes && <run your command>

schreibt 5 zufällige Bytes aus, die einen Cache-Miss erzwingen


10
Das Ergebnis des Schreibens dieser zufälligen Bytes wird ebenfalls zwischengespeichert. Wenn sich also vor diesem Befehl keine Dateien geändert haben, wird der Befehl nicht erneut ausgeführt. Das löst nichts.
Icy Defiance
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.