Docker Layer-Caching verstehen
Was dieser Artikel über Docker Layer-Caching behandelt
- Wie der Docker-Build-Cache funktioniert.
- Was Layer-Invalidierung verursacht.
- Wie man Cache-Mounts nutzt.
- Praktische Tipps für schnellere Builds.
- Cache in CI/CD und lokal.
Einleitung: Docker Layer-Caching verstehen
Jede Zeile in einem Dockerfile erzeugt einen Layer. Docker speichert diese Layer im Cache und verwendet sie erneut, wenn sich nichts geändert hat. Wer die Reihenfolge der Befehle richtig wählt, kann Build-Zeiten drastisch reduzieren. Doch eine einzelne geänderte Datei am Anfang des Dockerfiles kann alle folgenden Layer ungültig machen. Das Layer-Caching zu verstehen, ist deshalb zentral für effizientes Bauen von Docker-Images.
Dieser Artikel erklärt, wie der Cache arbeitet und wie man ihn optimal nutzt.
Wichtige Begriffe
- Layer: Schicht eines Docker-Images.
- Build-Cache: Zwischenspeicher für Layer.
- Cache-Invalidierung: Ungültigwerden eines Layers.
- BuildKit: Moderner Docker-Builder mit erweitertem Caching.
- Cache-Mount: Temporärer Cache innerhalb eines Builds.
- Pull-Through Cache: Zwischenspeicher für Images.
- Registry-Cache: Caching in einer Remote-Registry.
- Snapshot: Zwischenstand eines Layers.
Wie der Cache funktioniert
Beim Bau eines Images prüft Docker für jede Anweisung, ob bereits ein identischer Layer existiert. Falls ja, wird der Layer aus dem Cache wiederverwendet. Falls nein, wird der Layer neu gebaut und alle folgenden Layer ebenfalls.
Ein Layer gilt als unverändert, wenn:
- Der Befehl identisch ist.
- Die Eingabedateien identisch sind.
- Der vorherige Layer identisch ist.
Reihenfolge beachten
Dateien, die sich selten ändern, zuerst kopieren:
# Gut: Abhängigkeiten vor Quellcode
COPY package*.json ./
RUN npm ci
COPY . .
# Schlecht: Jede Code-Änderung invalidiert npm ci
COPY . .
RUN npm ci
Cache-Invalidierung
Jede Änderung an einer Datei, die vor einem COPY liegt, invalidiert den Cache. Das ist besonders wichtig bei Multi-Stage-Builds und Build-Abhängigkeiten.
Beispiel:
COPY package.json /app
RUN npm install
Wenn package.json geändert wird, muss npm install neu ausgeführt werden.
BuildKit Cache-Mounts
BuildKit erlaubt Cache-Mounts, die innerhalb eines Builds persistieren:
# syntax=docker/dockerfile:1.7
FROM python:3.11-slim
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
Das speichert den Pip-Cache zwischen Builds.
npm-Cache
# syntax=docker/dockerfile:1.7
FROM node:20-slim
RUN --mount=type=cache,target=/root/.npm \
npm ci
Maven-Cache
# syntax=docker/dockerfile:1.7
FROM maven:3.9-eclipse-temurin
RUN --mount=type=cache,target=/root/.m2 \
mvn package -DskipTests
Cache in CI/CD
In Continuous-Integration-Umgebungen ist der Cache oft nicht persistent. Lösungen:
docker buildxmitcache-fromundcache-to.- Externe Cache-Backends wie S3 oder Registry.
- Cache-Layer in der Docker-Registry.
docker buildx build \
--cache-from=type=registry,ref=user/image:cache \
--cache-to=type=registry,ref=user/image:cache,mode=max \
-t user/image:latest .
Lokalen Cache prüfen
docker system df
Cache löschen:
docker builder prune
Cache-Statistiken
BuildKit zeigt, welche Layer aus dem Cache kamen:
DOCKER_BUILDKIT=1 docker build --progress=plain .
Ausgabe wie CACHED zeigt wiederverwendete Layer.
Tipps für schnelle Builds
- Selten geänderte Dateien früh kopieren.
.dockerignoresetzen.RUNBefehle zusammenfassen, aber nur wenn sie zusammengehören.- Cache-Mounts nutzen.
- Nicht mehrfach
RUN apt-get updateallein ausführen. - CI-Cache extern speichern.
- Multistage-Builds kombinieren.
Typische Stolpersteine
- Cache ungültig:
COPY . .zu früh. - Zuviele Layer: Jede
RUNerzeugt eigenen Layer. - Cache bläht sich auf: Nie
docker builder pruneausführen. - CI ohne Cache: Jeder Build startet von null.
- Alte Basis-Images: Kein Caching der neuesten Sicherheitsupdates.
- Fehlende .dockerignore: Änderungen an irrelevanten Dateien invalidieren Layer.
Weiterführende Links und Infos
- BotServ.de Dockerfile schreiben
- BotServ.de Docker Multistage-Builds
- BotServ.de Docker Image-Optimierung
- BotServ.de Docker Befehle
FAQ: Docker Layer-Caching
Wie lange bleibt der Cache erhalten? Lokal bis zum manuellen Löschen, in CI meist zwischen den Builds.
Warum wird mein Cache ungültig? Weil sich Dateien, Befehle oder Basis-Images geändert haben.
Soll ich immer BuildKit nutzen? Ja, es bietet bessere Caching-Möglichkeiten.
Was ist ein Cache-Mount? Ein persistenter Speicher während des Builds, zum Beispiel für Paket-Caches.
Wie prüfe ich, ob Layer gecached sind?
Mit --progress=plain beim Build.
Quellen und weiterführende Literatur
- Docker Cache: https://docs.docker.com/build/cache/
- BuildKit: https://docs.docker.com/build/buildkit/
- Cache-Backends: https://docs.docker.com/build/cache/backends/
Zusammenfassung: Docker Layer-Caching verstehen
Docker Layer-Caching beschleunigt Builds erheblich, wenn die Reihenfolge der Anweisungen stimmt und seltener geänderte Dateien zuerst kopiert werden. BuildKit erweitert das Caching um Cache-Mounts für Paketmanager und externe Cache-Backends. .dockerignore, saubere Multistage-Builds und regelmässige Cache-Pflege sind wichtige Werkzeuge, um schnelle und reproduzierbare Builds zu erreichen. Wer den Cache versteht, spart Zeit sowohl lokal als auch in der CI/CD-Pipeline.


