36 Verwendung von Docker Caches

Das Caching von Docker-Containern in GitLab CI/CD spielt eine wichtige Rolle bei der Beschleunigung von Pipelines, insbesondere bei Projekten, die auf Docker-Containern basieren. Docker verwendet ein Schichtensystem, bei dem jede Anweisung in einem Dockerfile eine neue Schicht (Layer) erstellt. Diese Schichten können zwischen verschiedenen Build-Prozessen zwischengespeichert und wiederverwendet werden, was die Build-Zeiten erheblich reduziert. Das Docker-Caching optimiert den Build-Prozess, indem es sicherstellt, dass unveränderte Schichten nicht neu erstellt werden müssen.

36.1 Docker-Schichten und ihre Verwendung in GitLab

Docker-Images bestehen aus mehreren Schichten, die aufeinander aufbauen. Jede Anweisung im Dockerfile, wie RUN, COPY oder ADD, erzeugt eine neue Schicht. Diese Schichten werden im Docker-Cache gespeichert und können für zukünftige Builds wiederverwendet werden, wenn die Anweisungen im Dockerfile unverändert bleiben.

Beispiel für ein einfaches Dockerfile:

FROM node:14
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
CMD ["npm", "start"]

In diesem Beispiel erzeugen die Anweisungen COPY package.json und RUN npm install neue Schichten. Wenn das Dockerfile bei einem zukünftigen Build nicht geändert wird, kann Docker diese Schichten aus dem Cache wiederverwenden, anstatt die Befehle erneut auszuführen.

36.2 Nutzung des Docker-Caches in GitLab CI/CD

GitLab CI/CD unterstützt das Docker-Caching durch die Verwendung von GitLab-Runnern, die in Docker-Containern laufen. Dies bedeutet, dass Docker-Schichten zwischen Builds zwischengespeichert und wiederverwendet werden können, um die Build-Zeit zu verkürzen.

Konfiguration des Docker-Caches in der .gitlab-ci.yml-Datei:

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t myapp:latest .

In diesem Beispiel wird Docker-in-Docker (dind) verwendet, um einen Container zu erstellen. Docker speichert die Schichten im lokalen Cache und verwendet sie für zukünftige Builds, solange keine Änderungen im Dockerfile vorgenommen wurden.

36.3 Caching von Docker-Schichten mit --cache-from

Das Argument --cache-from beim Befehl docker build ermöglicht es, Schichten aus einem zuvor gebauten Image zu verwenden. Dies ist besonders nützlich, wenn die Builds in verschiedenen Umgebungen stattfinden oder wenn ein zentraler Docker-Cache in einer Registry wie Docker Hub oder der GitLab Container Registry verwendet wird.

Beispiel für die Nutzung von --cache-from:

build:
  stage: build
  script:
    - docker pull registry.gitlab.com/myproject/myapp:latest || true
    - docker build --cache-from registry.gitlab.com/myproject/myapp:latest -t myapp:latest .
    - docker push registry.gitlab.com/myproject/myapp:latest

Hier wird das zuletzt gebaute Docker-Image aus der Registry abgerufen und für den Cache verwendet. Wenn keine Änderungen vorgenommen wurden, können die bereits erstellten Schichten wiederverwendet werden, was die Build-Zeit erheblich verkürzt.

36.4 Best Practices für Docker-Caching

  1. Schichtreihenfolge optimieren: Die Reihenfolge der Befehle im Dockerfile kann die Effizienz des Caches beeinflussen. Häufig verwendete Anweisungen wie das Installieren von Abhängigkeiten sollten vor weniger häufigen Anweisungen wie dem Kopieren des Quellcodes stehen, um sicherzustellen, dass mehr Schichten zwischengespeichert werden können.

  2. Verwendung von Multi-Stage-Builds: Mit Multi-Stage-Builds können mehrere Stages in einem Dockerfile definiert werden, wodurch unnötige Dateien aus der endgültigen Version des Images entfernt werden können. Dies reduziert die Image-Größe und beschleunigt den Build-Prozess.

  3. Registry für Docker-Caching nutzen: Die Verwendung einer zentralen Docker-Registry wie der GitLab Container Registry oder Docker Hub ermöglicht es, den Docker-Cache über mehrere Build-Umgebungen hinweg zu teilen. Dies ist besonders nützlich, wenn Builds in verschiedenen CI/CD-Umgebungen oder bei mehreren Entwicklern ausgeführt werden.

  4. Schichten minimieren: Jedes RUN, COPY oder ADD erzeugt eine neue Schicht. Um den Cache effizient zu nutzen, sollten möglichst wenige Schichten erstellt werden, indem mehrere Befehle in einer einzigen Schicht kombiniert werden.

Beispiel:

RUN apt-get update && apt-get install -y curl git

Anstatt zwei separate RUN-Befehle zu verwenden, werden hier mehrere Befehle kombiniert, um nur eine Schicht zu erzeugen.


Weitere Informationen finden sich in der GitLab-Dokumentation.