Caching und Multistage
Ziel
In diesem Projekt geht es um den Cache und Multistage-Builds. Dazu werden wir auf dem zuvor geschriebenen Dockerfile und der Anwendung aufbauen.
Hilfsmittel
- Versuchen Sie zuerst, die unten stehenden Aufgaben mit Hilfe der Folien und des Cheatsheets 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
Using cache, z.B.:Step 7/7 : CMD ["python3", "app.py"] ---> Using cache ---> 6cf268ef7e57
1.2: Cache-busting in app.py
- Verändern Sie in
app.pyden String "Web App with Python Flask!". - Bauen Sie das Image erneut.
- Betrachten Sie die Ausgabe. Für Schritt 8 und 10 konnte nun nicht mehr 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.pyzu:return 'Hello World from Docker demo' - Führen Sie erneut
docker build -t demo01 .aus. - Die Ausgabe enthält nun bei Schritt 8 und 10 nicht mehr
Using cache, z.B.:Step 8/10 : COPY app.py . ---> f4ca72925a43 . . . . Step 10/10 : CMD ["python3", "app.py"] ---> Running in 4c2e3a45933b - Die Layer mussten erneut gebaut werden.
1.3: Cache-busting durch neue Systemabhängigkeiten
- Fügen Sie zu den bisherigen Systemabhängigkeiten
python3undpython3-pipnoch ein weiteres Paketnanohinzu. - 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 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 einen Namen.
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, die ,basierend auf der ersten Stage, weitere
Abhängigkeiten aus der
requirement.dev.txtinstalliert. Beachten Sie hierbei, dass vorher der User aufrootund danach wieder aufapp-runnergesetzt 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
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.