Caching und Multistage
Ziel
In diesem Projekt geht es um den Cache und Multistage-Builds. Sie werden:
- Cache-busting zu Ihrem Vorteil nutzen
- einen Multistage-Build erstellen und bauen
Hilfsmittel
- Versuchen Sie, die unten stehenden Aufgaben mit Hilfe der Folien und des Cheatsheets eigenständig zu lösen.
- Sollten Sie dabei Probleme haben, finden Sie bei jeder Aufgabe einen ausklappbaren Block, in dem der Lösungsweg beschrieben wird.
Vorbereitung
Stellen Sie sicher, dass Sie sich immernoch im Ordner mein-erstes-image
aus dem
vorherigen Hands-On befinden.
Aufgabe 1 - Layer und Caching
1.1: Bauen mit Cache
- Bauen Sie das Image erneut und beobachten Sie die Ausgabe.
- Für alle Layer wird der Cache verwendet. Es wird nichts erneut gebaut.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
-
Führen Sie erneut
aus.docker build -t demo01 .
-
Die Ausgabe enthält bei jedem Layer
CACHED
, z.B.:=> CACHED [5/7] COPY requirements.txt .
1.2: Cache-busting in app.py
- Verändern Sie in
app.py
den String "Web App with Python Flask!". - Bauen Sie das Image erneut.
- Betrachten Sie die Ausgabe. Es konnte nun nicht mehr in jedem Schritt der Cache verwendet werden.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Verändern Sie den Rückgabewert in Zeile 7 in
app.py
zu:return 'Hello World from Docker demo'
- Führen Sie erneut
docker build -t demo01 .
aus. - Die Ausgabe enthält nun bei Schritt 7 nicht mehr
CACHED
, z.B.:=> [7/7] COPY app.py .
- Das Layer musste erneut gebaut werden.
1.3: Cache-busting durch neue Systemabhängigkeiten
- Fügen Sie zu den bisherigen Systemabhängigkeiten
python3
undpython3-pip
noch ein weiteres Paketnano
hinzu. - Bauen Sie das Image erneut.
- Der Build dauert nun wieder länger, da die Systemabhängigkeiten erneut installiert werden müssen und der Cache nicht mehr verwendet werden konnte.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Ändern Sie das Dockerfile zu:
[...] RUN apt-get update && apt-get install -y \ python3 \ python3-pip \ nano \ && rm -rf /var/lib/apt/lists/* [...]
- Führen Sie erneut
aus.
docker build -t demo01 .
- Die Layer mussten erneut gebaut werden.
Aufgabe 2 - Multistage-Build
2.1: requirements.dev.txt anlegen
Erstellen Sie im Ordner mein-erstes-image
eine Datei requirements.dev.txt
mit dem Inhalt:
pylint
pytest
2.2: Dockerfile zu Multistage-Build erweitern
Wir wollen nun, basierend auf dem bisherigen, minimalen Image, weitere Entwicklungsabhängigkeiten installieren. Mit diesen könnte man in einer CI/CD-Pipeline Unit-/Integration-Tests und Code-Linting umsetzen. Die Abhängigkeiten sollen aber nicht im bisherigen, minimalen Image enthalten sein.
- Geben Sie der bisherigen Stage den Namen
runtime
.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Ändern Sie das Dockerfile zu:
FROM ubuntu:20.04 as runtime RUN apt-get update && apt-get install -y \ [...]
- Erstellen Sie eine zweite Stage
dev_environment
, die basierend auf der ersten Stage weitere Abhängigkeiten aus derrequirement.dev.txt
installiert. Beachten Sie hierbei, dass vorher der User aufroot
und danach wieder aufapp-runner-user
gesetzt werden muss, da nur der Root-User die Rechte für die Installationen hat.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Ändern Sie das Dockerfile zu:
[...] CMD ["python3", "app.py"] ## Zweite Stage FROM runtime as dev_environment USER root COPY requirements.dev.txt . RUN python3 -m pip install -r requirements.dev.txt USER app-runner-user
2.3: Multistage-Build bauen
Bauen Sie nun beide Stages.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Wenn Sie alle Stages bauen möchten, können Sie das, wie bisher, mit folgendem Befehl tun:
docker build -t demo01_dev .
Bauen Sie nun nur die erste Stage.
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Bauen Sie die erste Stage mit dem Namen
runtime
, wie folgt:docker build -t demo01 --target runtime .
Sie haben nun erfolgreich mit dem Cache und Multistage-Builds gearbeitet. Durch die Einbeziehung des Caches in den Erstellungsprozesses eines Dockerfiles lässt sich die Build-Zeit erheblich minimieren. Multistage-Builds eignen sich hervorragend um die Image-Größe zu minimieren.