Layer-Cache gezielt nutzen - Docker-Builds beschleunigen
Layer-Cache gezielt nutzen - Docker-Builds beschleunigen
Der Layer-Cache ist einer der größten Vorteile von Docker-Builds. Wer das Dockerfile falsch strukturiert, verliert ihn bei jeder Änderung — und wartet unnötig.
Wie der Cache funktioniert
Docker prüft beim Build jeden Layer: Hat sich die Instruktion oder ihr Input seit dem letzten Build verändert? Wenn nein, wird der gecachte Layer wiederverwendet. Wenn ja, wird der Layer neu gebaut — und alle folgenden Layer ebenfalls, egal ob sie sich geändert haben oder nicht.
Layer 1: FROM node:20-slim → Cache HIT
Layer 2: COPY package*.json . → Cache HIT (package.json unverändert)
Layer 3: RUN npm ci → Cache HIT (Dependencies unverändert)
Layer 4: COPY . . → Cache MISS (Quellcode geändert)
Layer 5: RUN npm run build → neu gebaut (wegen Layer 4)
Das wichtigste Prinzip: stabile Dinge zuerst
Alles, was sich selten ändert, gehört früh ins Dockerfile. Alles, was sich häufig ändert (Quellcode), kommt ans Ende.
# Schlecht: Quellcode wird zuerst kopiert
FROM node:20-slim
WORKDIR /app
COPY . . # Quellcode-Änderung invalidiert alles danach
RUN npm ci # npm install läuft bei JEDER Code-Änderung neu
RUN npm run build
# Richtig: Dependencies zuerst, Quellcode zuletzt
FROM node:20-slim
WORKDIR /app
COPY package.json package-lock.json ./ # nur wenn package.json sich ändert
RUN npm ci # gecacht solange package.json gleich bleibt
COPY . . # Code-Änderungen hier — npm ci bleibt cached
RUN npm run build
Mit der richtigen Reihenfolge dauert ein Build nach einer Code-Änderung Sekunden statt Minuten.
Der package.json-Trick für Python
Dasselbe Muster gilt für Python:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt . # nur wenn requirements.txt sich ändert
RUN pip install -r requirements.txt # gecacht
COPY . . # Code-Änderungen invalidieren ab hier
Systemabhängigkeiten vor App-Code
FROM python:3.12-slim
# System-Pakete: ändert sich selten → früh rein
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install -r requirements.txt
# Quellcode: ändert sich oft → ganz am Ende
COPY . .
Cache deaktivieren
Manchmal will man einen frischen Build ohne Cache — z. B. wenn man sicherstellen muss, dass apt-get update die aktuellen Paketlisten holt:
docker build --no-cache -t myapp .
Cache für Remote-Builds teilen
Bei CI/CD-Pipelines (GitHub Actions, GitLab CI) gibt es keinen lokalen Layer-Cache zwischen Runs. Lösung: Registry als Cache nutzen:
docker buildx build \
--cache-from type=registry,ref=myregistry/myapp:cache \
--cache-to type=registry,ref=myregistry/myapp:cache,mode=max \
-t myregistry/myapp:latest .