Ich bin erstaunt, wie gut Docker Caching von Layern funktioniert, aber ich frage mich auch, wie es bestimmt, ob es einen Cache-Layer verwenden kann oder nicht.
Nehmen wir diese Build-Schritte zum Beispiel:
%Vor% Wie weiß es zum Beispiel, dass es die zwischengespeicherte Ebene für npm install -g node-gyp
verwenden kann, aber eine neue Ebene für npm install
erstellt?
Der Build-Cache-Prozess wird ausführlich im Dockerfile-Best Practices-Build erläutert Cache Abschnitt.
Ausgehend von einem Basisbild, das sich bereits im Cache befindet, wird der nächste Befehl mit allen daraus abgeleiteten Kindbildern verglichen Basisbild, um zu sehen, ob einer von ihnen mit genau dem gleichen erstellt wurde Anweisung. Wenn nicht, wird der Cache ungültig gemacht.
In den meisten Fällen genügt es, die Anweisung in
Dockerfile
mit einem der Kindbilder zu vergleichen. Allerdings, gewiss Anweisungen erfordern ein wenig mehr Prüfung und Erklärung.Bei den Befehlen
ADD
undCOPY
wird der Inhalt der Datei (en) im Bild untersucht und für jede Datei eine Prüfsumme berechnet. Die zuletzt geänderten und zuletzt aufgerufenen Zeiten der Datei (en) sind nicht in diesen Prüfsummen berücksichtigt. Während der Cache-Suche, die Prüfsumme wird mit der Prüfsumme in den vorhandenen Bildern verglichen. Wenn überhaupt hat sich dann in den Dateien geändert, zB den Inhalten und den Metadaten Der Cache wird ungültig gemacht.Abgesehen von den Befehlen
ADD
undCOPY
prüft die Cacheüberprüfung nicht die Dateien im Container, um eine Cacheübereinstimmung zu ermitteln. Zum Beispiel, wenn Sie einenRUN apt-get -y update
-Befehl für die Dateien verarbeiten aktualisiert im Container wird nicht überprüft, um festzustellen, ob ein Cache vorhanden ist Treffer existiert. In diesem Fall wird nur die Befehlszeichenfolge selbst verwendet um eine Übereinstimmung zu finden.Sobald der Cache ungültig ist, werden alle nachfolgenden
Dockerfile
-Befehle ausgeführt erzeugt neue Bilder und der Cache wird nicht verwendet.
Sie werden in Situationen geraten, in denen OS-Pakete, NPM-Pakete oder ein Git Repo auf neuere Versionen aktualisiert werden (sagen wir ~2.3
sherver in package.json
), aber da Ihre Dockerfile
oder package.json
nicht aktualisiert wurde, Andockfenster verwendet den Cache weiterhin.
Es ist möglich, programmatisch ein Dockerfile
zu generieren, das den Cache zerstört, indem Zeilen bei bestimmten intelligenteren Überprüfungen geändert werden (z. B. das letzte git branch shasum aus einem Repo abrufen, um es in der Klonanweisung zu verwenden). Sie können den Build auch regelmäßig mit --no-cache=true
ausführen, um Aktualisierungen zu erzwingen.
Es liegt daran, dass Ihre package.json
-Datei geändert wurde, siehe Removing intermediate container
.
Das ist normalerweise auch der Grund, warum Paket-Manager-Dateien (Hersteller / Drittanbieter) COPY
zuerst während docker build
erscheinen. Danach führen Sie die Installation des Paketmanagers aus und fügen dann den Rest Ihrer Anwendung hinzu, d. H.% Co_de%.
Wenn Sie keine Änderungen an Ihren Bibliotheken vornehmen, werden diese Schritte vom Build-Cache aus ausgeführt.