Fortgeschrittene Dockerfile-Techniken

DockerDockerBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden wir tiefer in die Techniken von Dockerfiles eintauchen und fortgeschrittene Konzepte erkunden, die Ihnen helfen, effizientere und flexiblere Docker-Images zu erstellen. Wir werden detaillierte Dockerfile-Anweisungen, Mehrstufen-Builds und die Verwendung von.dockerignore-Dateien behandeln. Außerdem werden wir das entscheidende Konzept der Ebenen (layers) in Docker-Images untersuchen. Am Ende dieses Labs werden Sie ein umfassendes Verständnis dieser fortgeschrittenen Dockerfile-Techniken haben und in der Lage sein, sie auf Ihre eigenen Projekte anzuwenden.

Dieses Lab ist für Anfänger konzipiert und bietet detaillierte Erklärungen sowie die Klärung möglicher Verständnisschwierigkeiten. Wir werden WebIDE (VS Code) für alle unsere Dateibearbeitungsaufgaben verwenden, was es einfach macht, Dateien direkt im Browser zu erstellen und zu ändern.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) linux(("Linux")) -.-> linux/FileandDirectoryManagementGroup(["File and Directory Management"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/logs("View Container Logs") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") linux/BasicFileOperationsGroup -.-> linux/touch("File Creating/Updating") docker/ImageOperationsGroup -.-> docker/images("List Images") linux/FileandDirectoryManagementGroup -.-> linux/mkdir("Directory Creating") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/run -.-> lab-389027{{"Fortgeschrittene Dockerfile-Techniken"}} docker/ps -.-> lab-389027{{"Fortgeschrittene Dockerfile-Techniken"}} docker/logs -.-> lab-389027{{"Fortgeschrittene Dockerfile-Techniken"}} docker/inspect -.-> lab-389027{{"Fortgeschrittene Dockerfile-Techniken"}} linux/touch -.-> lab-389027{{"Fortgeschrittene Dockerfile-Techniken"}} docker/images -.-> lab-389027{{"Fortgeschrittene Dockerfile-Techniken"}} linux/mkdir -.-> lab-389027{{"Fortgeschrittene Dockerfile-Techniken"}} docker/build -.-> lab-389027{{"Fortgeschrittene Dockerfile-Techniken"}} end

Verständnis von Dockerfile-Anweisungen und Ebenen (layers)

Beginnen wir damit, ein Dockerfile zu erstellen, das verschiedene Anweisungen nutzt. Wir werden ein Image für eine Python-Webanwendung mit Flask erstellen und dabei untersuchen, wie jede Anweisung zu den Ebenen (layers) unseres Docker-Images beiträgt.

  1. Zunächst erstellen wir ein neues Verzeichnis für unser Projekt. Führen Sie im WebIDE-Terminal folgenden Befehl aus:
mkdir -p ~/project/advanced-dockerfile && cd ~/project/advanced-dockerfile

Dieser Befehl erstellt ein neues Verzeichnis namens advanced-dockerfile im project-Ordner und wechselt dann in dieses Verzeichnis.

  1. Jetzt erstellen wir unsere Anwendungsdatei. Klicken Sie im WebIDE-Dateiexplorer (normalerweise auf der linken Seite des Bildschirms) mit der rechten Maustaste auf den advanced-dockerfile-Ordner und wählen Sie "Neue Datei". Benennen Sie diese Datei app.py.

  2. Öffnen Sie app.py und fügen Sie folgenden Python-Code hinzu:

from flask import Flask
import os

app = Flask(__name__)

@app.route('/')
def hello():
    return f"Hello from {os.environ.get('ENVIRONMENT', 'unknown')} environment!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Dies ist eine einfache Flask-Anwendung, die eine Begrüßungsnachricht einschließlich der Umgebung, in der sie läuft, zurückgibt.

  1. Als Nächstes müssen wir eine requirements.txt-Datei erstellen, um unsere Python-Abhängigkeiten zu spezifizieren. Erstellen Sie eine neue Datei namens requirements.txt im gleichen Verzeichnis und fügen Sie folgenden Inhalt hinzu:
Flask==2.0.1
Werkzeug==2.0.1

Hier geben wir exakte Versionen für Flask und Werkzeug an, um die Kompatibilität sicherzustellen.

  1. Jetzt erstellen wir unser Dockerfile. Erstellen Sie eine neue Datei namens Dockerfile (mit großem 'D') im gleichen Verzeichnis und fügen Sie folgenden Inhalt hinzu:
## Use an official Python runtime as the base image
FROM python:3.9-slim

## Set the working directory in the container
WORKDIR /app

## Set an environment variable
ENV ENVIRONMENT=production

## Copy the requirements file into the container
COPY requirements.txt.

## Install the required packages
RUN pip install --no-cache-dir -r requirements.txt

## Copy the application code into the container
COPY app.py.

## Specify the command to run when the container starts
CMD ["python", "app.py"]

## Expose the port the app runs on
EXPOSE 5000

## Add labels for metadata
LABEL maintainer="Your Name <[email protected]>"
LABEL version="1.0"
LABEL description="Flask app demo for advanced Dockerfile techniques"

Jetzt zerlegen wir diese Anweisungen und verstehen, wie sie zu den Ebenen (layers) unseres Docker-Images beitragen:

  • FROM python:3.9-slim: Dies ist immer die erste Anweisung. Sie gibt das Basisimage an, von dem wir aus bauen. Dies erstellt die erste Ebene (layer) unseres Images, die die Python-Laufzeitumgebung enthält.
  • WORKDIR /app: Dies legt das Arbeitsverzeichnis für nachfolgende Anweisungen fest. Es erstellt keine neue Ebene (layer), sondern beeinflusst das Verhalten folgender Anweisungen.
  • ENV ENVIRONMENT=production: Dies setzt eine Umgebungsvariable. Umgebungsvariablen erstellen keine neuen Ebenen (layers), sondern werden in den Image-Metadaten gespeichert.
  • COPY requirements.txt.: Dies kopiert die requirements.txt-Datei von unserem Host in das Image. Dies erstellt eine neue Ebene (layer), die nur diese Datei enthält.
  • RUN pip install --no-cache-dir -r requirements.txt: Dies führt einen Befehl im Container während des Build-Prozesses aus. Es installiert unsere Python-Abhängigkeiten. Dies erstellt eine neue Ebene (layer), die alle installierten Pakete enthält.
  • COPY app.py.: Dies kopiert unseren Anwendungs-Code in das Image und erstellt damit eine weitere Ebene (layer).
  • CMD ["python", "app.py"]: Dies gibt den Befehl an, der ausgeführt wird, wenn der Container startet. Es erstellt keine Ebene (layer), sondern legt den Standardbefehl für den Container fest.
  • EXPOSE 5000: Dies ist eigentlich nur eine Art Dokumentation. Es teilt Docker mit, dass der Container zur Laufzeit auf diesem Port lauschen wird, veröffentlicht den Port aber nicht tatsächlich. Es erstellt keine Ebene (layer).
  • LABEL...: Diese fügen Metadaten zum Image hinzu. Wie die ENV-Anweisungen erstellen sie keine neuen Ebenen (layers), sondern werden in den Image-Metadaten gespeichert.

Jede RUN-, COPY- und ADD-Anweisung in einem Dockerfile erstellt eine neue Ebene (layer). Ebenen (layers) sind ein grundlegendes Konzept in Docker, das eine effiziente Speicherung und Übertragung von Images ermöglicht. Wenn Sie Änderungen an Ihrem Dockerfile vornehmen und das Image neu erstellen, wird Docker die zwischengespeicherten Ebenen (layers) wiederverwenden, die sich nicht geändert haben, was den Build-Prozess beschleunigt.

  1. Jetzt, da wir verstehen, was unser Dockerfile tut, erstellen wir das Docker-Image. Führen Sie im Terminal folgenden Befehl aus:
docker build -t advanced-flask-app.

Dieser Befehl erstellt ein neues Docker-Image mit dem Tag advanced-flask-app. Der Punkt am Ende sagt Docker, dass es das Dockerfile im aktuellen Verzeichnis suchen soll.

Sie werden eine Ausgabe sehen, die jeden Schritt des Build-Prozesses anzeigt. Beachten Sie, wie jeder Schritt einer Anweisung in unserem Dockerfile entspricht und wie Docker "Using cache" (Zwischenspeicher wird verwendet) für Schritte erwähnt, die sich nicht geändert haben, wenn Sie den Build-Befehl mehrmals ausführen.

  1. Sobald der Build-Prozess abgeschlossen ist, können wir einen Container auf der Grundlage unseres neuen Images ausführen:
docker run -d -p 5000:5000 --name flask-container advanced-flask-app

Dieser Befehl macht Folgendes:

  • -d führt den Container im detached-Modus (im Hintergrund) aus.
  • -p 5000:5000 bildet Port 5000 auf Ihrem Host auf Port 5000 im Container ab.
  • --name flask-container gibt unserem neuen Container einen Namen.
  • advanced-flask-app ist das Image, das wir zum Erstellen des Containers verwenden.

Sie können überprüfen, ob der Container läuft, indem Sie die Liste der laufenden Container prüfen:

docker ps
  1. Um zu testen, ob unsere Anwendung korrekt läuft, können wir den curl-Befehl verwenden:
curl http://localhost:5000

Sie sollten die Nachricht "Hello from production environment!" sehen.

Wenn Sie Probleme mit curl haben, können Sie auch einen neuen Browser-Tab öffnen und http://localhost:5000 besuchen. Sie sollten die gleiche Nachricht sehen.

Wenn Sie auf Probleme stoßen, können Sie die Container-Logs mit folgendem Befehl überprüfen:

docker logs flask-container

Dies zeigt Ihnen alle Fehlermeldungen oder Ausgaben Ihrer Flask-Anwendung.

Mehrstufen-Builds

Nachdem wir nun die grundlegenden Dockerfile-Anweisungen und Ebenen (layers) verstanden haben, wollen wir uns eine fortgeschrittenere Technik ansehen: Mehrstufen-Builds. Mehrstufen-Builds ermöglichen es Ihnen, mehrere FROM-Anweisungen in Ihrem Dockerfile zu verwenden. Dies ist besonders nützlich, um kleinere End-Images zu erstellen, indem Sie nur die notwendigen Artefakte von einer Stufe zur nächsten kopieren.

Ändern wir nun unser Dockerfile, um einen Mehrstufen-Build zu verwenden, der tatsächlich ein kleineres Image ergibt:

  1. Öffnen Sie im WebIDE das Dockerfile, das wir zuvor erstellt haben.
  2. Ersetzen Sie den gesamten Inhalt durch Folgendes:
## Build stage
FROM python:3.9-slim AS builder

WORKDIR /app

COPY requirements.txt.

RUN pip install --user --no-cache-dir -r requirements.txt

## Final stage
FROM python:3.9-slim

WORKDIR /app

## Copy only the installed packages from the builder stage
COPY --from=builder /root/.local /root/.local
COPY app.py.

ENV PATH=/root/.local/bin:$PATH
ENV ENVIRONMENT=production

CMD ["python", "app.py"]

EXPOSE 5000

LABEL maintainer="Your Name <[email protected]>"
LABEL version="1.0"
LABEL description="Flask app demo with multi-stage build"

Lassen Sie uns analysieren, was in diesem Mehrstufen-Dockerfile passiert:

  1. Wir beginnen mit einer builder-Stufe:

    • Wir verwenden das Python 3.9-slim-Image als Basis, um von Anfang an die Größe klein zu halten.
    • Wir installieren unsere Python-Abhängigkeiten in dieser Stufe mit pip install --user. Dadurch werden die Pakete im Home-Verzeichnis des Benutzers installiert.
  2. Dann haben wir unsere Endstufe:

    • Wir beginnen neu mit einem anderen Python 3.9-slim-Image.
    • Wir kopieren nur die installierten Pakete aus der builder-Stufe, genauer aus /root/.local, wo pip install --user sie platziert hat.
    • Wir kopieren unseren Anwendungs-Code.
    • Wir fügen das lokale Binärverzeichnis dem PATH hinzu, damit Python die installierten Pakete finden kann.
    • Wir richten den Rest unseres Containers (ENV, CMD, EXPOSE, LABEL) wie zuvor ein.

Der entscheidende Vorteil hierbei ist, dass unser End-Image keine der Build-Tools oder Caches aus dem pip-Installationsprozess enthält. Es enthält nur die endgültigen, notwendigen Artefakte. Dies sollte zu einem kleineren Image führen.

  1. Bauen wir nun dieses neue Mehrstufen-Image. Führen Sie im Terminal folgenden Befehl aus:
docker build -t multi-stage-flask-app.
  1. Sobald der Build-Prozess abgeschlossen ist, vergleichen wir die Größen unserer beiden Images. Führen Sie folgenden Befehl aus:
docker images | grep flask-app
multi-stage-flask-app         latest     7bdd1be2d1fb   10 seconds ago   129MB
advanced-flask-app            latest     c59d6fa303cc   10 minutes ago   136MB

Sie sollten nun sehen, dass das multi-stage-flask-app kleiner ist als das advanced-flask-app, das wir zuvor erstellt haben.

  1. Jetzt lassen wir einen Container mit unserem neuen, schlankeren Image laufen:
docker run -d -p 5001:5000 --name multi-stage-container multi-stage-flask-app

Beachten Sie, dass wir einen anderen Host-Port (5001) verwenden, um Konflikte mit unserem vorherigen Container zu vermeiden.

  1. Testen Sie die Anwendung:
curl http://localhost:5001

Sie sollten immer noch die Nachricht "Hello from production environment!" sehen.

  1. Um die Unterschiede zwischen unserem Einstufen- und Mehrstufen-Image besser zu verstehen, können wir den docker history-Befehl verwenden. Führen Sie diese Befehle aus:
docker history advanced-flask-app
docker history multi-stage-flask-app

Vergleichen Sie die Ausgaben. Sie sollten bemerken, dass der Mehrstufen-Build weniger Ebenen (layers) hat und einige Ebenen kleiner sind.

Mehrstufen-Builds sind eine leistungsstarke Technik zur Erstellung effizienter Docker-Images. Sie ermöglichen es Ihnen, Tools und Dateien in Ihrem Build-Prozess zu verwenden, ohne Ihr End-Image aufzublähen. Dies ist besonders nützlich für kompilierte Sprachen oder Anwendungen mit komplexen Build-Prozessen.

In diesem Fall haben wir es verwendet, um ein kleineres Python-Anwendungs-Image zu erstellen, indem wir nur die notwendigen installierten Pakete und den Anwendungs-Code kopieren und alle Build-Artefakte oder Caches zurücklassen.

Verwendung der.dockerignore-Datei

Beim Erstellen eines Docker-Images sendet Docker alle Dateien im Verzeichnis an den Docker-Daemon. Wenn Sie große Dateien haben, die für das Erstellen Ihres Images nicht benötigt werden, kann dies den Build-Prozess verlangsamen. Die .dockerignore-Datei ermöglicht es Ihnen, Dateien und Verzeichnisse anzugeben, die beim Erstellen eines Docker-Images ausgeschlossen werden sollen.

Erstellen wir nun eine .dockerignore-Datei und sehen, wie sie funktioniert:

  1. Erstellen Sie im WebIDE eine neue Datei im advanced-dockerfile-Verzeichnis und benennen Sie sie .dockerignore.
  2. Fügen Sie folgenden Inhalt zur .dockerignore-Datei hinzu:
**/.git
**/.gitignore
**/__pycache__
**/*.pyc
**/*.pyo
**/*.pyd
**/.Python
**/env
**/venv
**/ENV
**/env.bak
**/venv.bak

Lassen Sie uns analysieren, was diese Muster bedeuten:

  • **/.git: Ignorieren Sie das .git-Verzeichnis und seinen gesamten Inhalt, unabhängig davon, wo es in der Verzeichnisstruktur erscheint.
  • **/.gitignore: Ignorieren Sie .gitignore-Dateien.
  • **/__pycache__: Ignorieren Sie Python-Cache-Verzeichnisse.
  • **/*.pyc, **/*.pyo, **/*.pyd: Ignorieren Sie kompilierte Python-Dateien.
  • **/.Python: Ignorieren Sie .Python-Dateien (oft von virtuellen Umgebungen erstellt).
  • **/env, **/venv, **/ENV: Ignorieren Sie virtuelle Umgebungsverzeichnisse.
  • **/env.bak, **/venv.bak: Ignorieren Sie Sicherungskopien von virtuellen Umgebungsverzeichnissen.

Das ** am Anfang jeder Zeile bedeutet "in jedem Verzeichnis".

  1. Um die Wirkung der .dockerignore-Datei zu demonstrieren, erstellen wir einige Dateien, die wir ignorieren möchten. Führen Sie im Terminal folgenden Befehl aus:
mkdir venv
touch venv/ignore_me.txt
touch.gitignore

Diese Befehle erstellen ein venv-Verzeichnis mit einer Datei darin und eine .gitignore-Datei. Dies sind übliche Elemente in Python-Projekten, die wir normalerweise nicht in unseren Docker-Images haben möchten.

  1. Jetzt erstellen wir unser Image erneut:
docker build -t ignored-flask-app.
  1. Um zu überprüfen, dass die ignorierten Dateien nicht im Build-Kontext enthalten waren, können wir den docker history-Befehl verwenden:
docker history ignored-flask-app

Sie sollten keine Schritte sehen, die das venv-Verzeichnis oder die .gitignore-Datei kopieren.

Die .dockerignore-Datei ist ein leistungsstarkes Werkzeug, um Ihre Docker-Images sauber zu halten und Ihren Build-Prozess effizient zu gestalten. Sie ist besonders nützlich für größere Projekte, bei denen Sie möglicherweise viele Dateien haben, die im End-Image nicht benötigt werden.

Fortgeschrittene Dockerfile-Anweisungen

In diesem letzten Schritt werden wir einige zusätzliche Dockerfile-Anweisungen und bewährte Verfahren untersuchen, die dazu beitragen können, Ihre Docker-Images sicherer, wartbarer und einfacher zu verwenden zu machen. Wir werden uns auch auf die Fehlerbehebung und die Überprüfung jeder Stufe des Prozesses konzentrieren.

  1. Öffnen Sie in der WebIDE erneut die Dockerfile.

  2. Ersetzen Sie den Inhalt durch Folgendes:

## Build stage
FROM python:3.9-slim AS builder

WORKDIR /app

COPY requirements.txt.
RUN pip install --user --no-cache-dir -r requirements.txt

## Final stage
FROM python:3.9-slim

## Create a non-root user
RUN useradd -m appuser

## Install curl for healthcheck
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

WORKDIR /app

## Dynamically determine Python version and site-packages path
RUN PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') && \
    SITE_PACKAGES_PATH="/home/appuser/.local/lib/python${PYTHON_VERSION}/site-packages" && \
    mkdir -p "${SITE_PACKAGES_PATH}" && \
    chown -R appuser:appuser /home/appuser/.local

## Copy site-packages and binaries using the variable
COPY --from=builder /root/.local/lib/python3.9/site-packages "${SITE_PACKAGES_PATH}"
COPY --from=builder /root/.local/bin /home/appuser/.local/bin
COPY app.py.

ENV PATH=/home/appuser/.local/bin:$PATH
ENV ENVIRONMENT=production

## Set the user to run the application
USER appuser

## Use ENTRYPOINT with CMD
ENTRYPOINT ["python"]
CMD ["app.py"]

EXPOSE 5000

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:5000/ || exit 1

ARG BUILD_VERSION
LABEL maintainer="Your Name <[email protected]>"
LABEL version="${BUILD_VERSION:-1.0}"
LABEL description="Flask app demo with advanced Dockerfile techniques"

Lassen Sie uns die neuen Konzepte, die in diesem Dockerfile eingeführt wurden, analysieren:

  • RUN useradd -m appuser: Dies erstellt einen neuen Benutzer namens appuser im Container. Das Ausführen von Anwendungen als Nicht-Root-Benutzer ist eine bewährte Sicherheitsmethode, da es den potenziellen Schaden begrenzt, wenn die Anwendung kompromittiert wird. Das -m-Flag erstellt ein Heimatverzeichnis für den Benutzer.
  • RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*: Dies installiert das curl-Paket, das für die Ausführung unserer HEALTHCHECK-Anweisung erforderlich ist. Wir bereinigen auch den apt-Cache, um die Größe des Images zu reduzieren.
  • RUN PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') &&...: Diese Befehlssammlung ermittelt dynamisch die Python-Version im Container und erstellt das richtige site-packages-Verzeichnis für den appuser. Sie setzt auch die richtigen Berechtigungen für das lokale Verzeichnis des Benutzers.
  • COPY --from=builder /root/.local/lib/python3.9/site-packages "${SITE_PACKAGES_PATH}": Diese Anweisung kopiert die installierten Python-Pakete aus der builder-Stufe in den dynamisch ermittelten site-packages-Pfad im finalen Image, um sicherzustellen, dass die Pakete an der richtigen Stelle für den appuser platziert werden.
  • COPY --from=builder /root/.local/bin /home/appuser/.local/bin: Dies kopiert ausführbare Skripte, die von pip installiert wurden (z. B. die Befehlszeilenschnittstelle von Flask, falls vorhanden), aus der builder-Stufe in das lokale bin-Verzeichnis des appuser.
  • ENTRYPOINT ["python"] mit CMD ["app.py"]: Wenn zusammen verwendet, definiert ENTRYPOINT das Hauptausführbare für den Container (in diesem Fall python), und CMD liefert die Standardargumente für dieses Ausführbare (app.py). Dieses Muster ermöglicht Flexibilität: Benutzer können den Container ausführen und standardmäßig app.py ausführen, oder sie können CMD überschreiben, um andere Python-Skripte oder Befehle auszuführen.
  • HEALTHCHECK: Diese Anweisung konfiguriert eine Integritätsprüfung für den Container. Docker führt periodisch den angegebenen Befehl (curl -f http://localhost:5000/) aus, um zu bestimmen, ob der Container gesund ist. Die Flags --interval=30s und --timeout=3s setzen das Prüfintervall bzw. das Timeout. Wenn der curl-Befehl fehlschlägt (gibt einen Exit-Code ungleich Null zurück), wird der Container als ungesund angesehen.
  • ARG BUILD_VERSION: Dies definiert ein Build-Argument namens BUILD_VERSION. Build-Argumente ermöglichen es Ihnen, Werte zur Build-Zeit in das Docker-Image zu übergeben.
  • LABEL version="${BUILD_VERSION:-1.0}": Dies setzt ein Label namens version auf dem Docker-Image. Es verwendet das Build-Argument BUILD_VERSION. Wenn BUILD_VERSION während des Builds angegeben wird, wird sein Wert verwendet; andernfalls wird standardmäßig 1.0 verwendet (unter Verwendung der :--Syntax für Standardwerte).
  1. Jetzt lassen Sie uns dieses neue Image erstellen und eine Build-Version angeben:
docker build -t advanced-flask-app-v2 --build-arg BUILD_VERSION=2.0.

Das Flag --build-arg BUILD_VERSION=2.0 ermöglicht es uns, den Wert 2.0 für das Build-Argument BUILD_VERSION während des Image-Build-Prozesses zu übergeben. Dieser Wert wird verwendet, um das version-Label im Docker-Image zu setzen.

  1. Sobald der Build abgeschlossen ist, lassen Sie uns überprüfen, ob das Image erfolgreich erstellt wurde:
docker images | grep advanced-flask-app-v2

Sie sollten das neue Image advanced-flask-app-v2 in der Ausgabe des Befehls docker images sehen, zusammen mit seinem Tag, der Image-ID, dem Erstellungsdatum und der Größe.

  1. Jetzt lassen Sie uns einen Container mit dem neuen Image ausführen:
docker run -d -p 5002:5000 --name advanced-container-v2 advanced-flask-app-v2

Dieser Befehl führt einen Container im detached-Modus (-d) aus, bildet Port 5002 auf Ihrem Host auf Port 5000 im Container ab (-p 5002:5000), benennt den Container advanced-container-v2 (--name advanced-container-v2) und verwendet das advanced-flask-app-v2-Image, um den Container zu erstellen.

  1. Lassen Sie uns überprüfen, ob der Container läuft:
docker ps | grep advanced-container-v2

Wenn der Container erfolgreich läuft, sollten Sie ihn in der Ausgabe des Befehls docker ps sehen. Wenn Sie den Container nicht in der Liste sehen, ist er möglicherweise beendet. Lassen Sie uns nach allen gestoppten Containern suchen:

docker ps -a | grep advanced-container-v2

Wenn Sie den Container in der Ausgabe von docker ps -a sehen, aber er nicht läuft (Status ist nicht "Up"), können wir seine Logs auf Fehler überprüfen:

docker logs advanced-container-v2

Dieser Befehl zeigt die Logs des Containers advanced-container-v2 an, was bei der Diagnose von Startproblemen oder Laufzeitfehlern in Ihrer Flask-Anwendung helfen kann.

  1. Angenommen, der Container läuft. Nach einer kurzen Wartezeit, um dem Container Zeit zum Starten zu geben, können wir seinen Integritätsstatus überprüfen:
docker inspect --format='{{.State.Health.Status}}' advanced-container-v2

Nach einer kurzen Verzögerung (um sicherzustellen, dass die Integritätsprüfung mindestens einmal ausgeführt wurde) sollten Sie "healthy" als Ausgabe sehen. Wenn Sie zunächst "unhealthy" sehen, warten Sie weitere 30 Sekunden (das Integritätsprüfintervall) und führen Sie den Befehl erneut aus. Wenn der Status weiterhin "unhealthy" bleibt, überprüfen Sie die Container-Logs mit docker logs advanced-container-v2 auf potenzielle Probleme mit Ihrer Flask-Anwendung. Wenn es keine offensichtlichen Probleme gibt, können Sie den "unhealthy"-Status ignorieren.

  1. Wir können auch überprüfen, ob unser Build-Version-Label korrekt angewendet wurde:
docker inspect -f '{{.Config.Labels.version}}' advanced-flask-app-v2

Dieser Befehl ruft den Wert des version-Labels aus dem advanced-flask-app-v2-Image ab und zeigt ihn an. Sie sollten "2.0" als Ausgabe sehen, was bestätigt, dass das Build-Argument BUILD_VERSION korrekt verwendet wurde, um das Label zu setzen.

  1. Schließlich lassen Sie uns unsere Anwendung testen, indem wir eine Anfrage an sie senden:
curl http://localhost:5002

Sie sollten die Nachricht "Hello from production environment!" in der Ausgabe sehen. Dies zeigt an, dass Ihre Flask-Anwendung korrekt im Docker-Container läuft und auf Port 5002 Ihres Hosts erreichbar ist.

Diese fortgeschrittenen Techniken ermöglichen es Ihnen, sicherere, konfigurierbare und produktionsreife Docker-Images zu erstellen. Der Nicht-Root-Benutzer verbessert die Sicherheit, die HEALTHCHECK-Anweisung erleichtert die Container-Orchestrierung und -Überwachung, und Build-Argumente ermöglichen eine flexiblere und versionsbasierte Image-Erstellung.

Zusammenfassung

In diesem Lab haben wir fortgeschrittene Dockerfile-Techniken untersucht, die Ihnen helfen, effizientere, sicherere und wartbarere Docker-Images zu erstellen. Wir haben folgende Themen behandelt:

  1. Detaillierte Dockerfile-Anweisungen und ihre Auswirkungen auf Image-Ebenen (layers): Wir haben gelernt, wie jede Anweisung zur Struktur unseres Docker-Images beiträgt und wie das Verständnis von Ebenen (layers) uns bei der Optimierung unserer Images helfen kann.
  2. Mehrstufen-Builds: Wir haben diese Technik verwendet, um kleinere End-Images zu erstellen, indem wir unsere Build-Umgebung von unserer Laufzeitumgebung trennen.
  3. Verwendung von.dockerignore-Dateien: Wir haben gelernt, wie wir unnötige Dateien aus unserem Build-Kontext ausschließen können, was Builds beschleunigen und die Image-Größe reduzieren kann.
  4. Fortgeschrittene Dockerfile-Anweisungen: Wir haben zusätzliche Anweisungen wie USER, ENTRYPOINT, HEALTHCHECK und ARG untersucht, die es uns ermöglichen, sicherere und flexiblere Images zu erstellen.

Diese Techniken ermöglichen es Ihnen:

  • Optimiertere und kleinere Docker-Images zu erstellen
  • Die Sicherheit zu verbessern, indem Sie Anwendungen als Nicht-Root-Benutzer ausführen
  • Integritätsprüfungen (health checks) für eine bessere Container-Orchestrierung zu implementieren
  • Build-Zeit-Variablen für eine flexiblere Image-Erstellung zu verwenden

Während dieses Labs haben wir das WebIDE (VS Code) verwendet, um unsere Dateien zu bearbeiten. Dies erleichtert es, Dockerfiles und Anwendungs-Code direkt im Browser zu erstellen und zu ändern. Dieser Ansatz ermöglicht ein nahtloses Entwicklungs-Erlebnis bei der Arbeit mit Docker.