Wertschöpfung mit benutzerdefinierten Docker-Images

DockerDockerBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

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

Einführung

In diesem Lab bauen wir auf unserem Wissen aus Lab 1, in dem wir Docker-Befehle verwendet haben, um Container auszuführen. Wir werden ein benutzerdefiniertes Docker-Image erstellen, das auf Grundlage einer Dockerfile erstellt wird. Nachdem wir das Image erstellt haben, werden wir es in einen zentralen Registrierungsdienst pushen, von dem es abgerufen werden kann, um in anderen Umgebungen bereitgestellt zu werden. Darüber hinaus werden wir kurz die Image-Schichten beschreiben und erklären, wie Docker "Copy-on-Write" und das Union-Dateisystem nutzt, um Bilder effizient zu speichern und Container auszuführen.

Wir werden in diesem Lab einige Docker-Befehle verwenden. Für die vollständige Dokumentation zu den verfügbaren Befehlen konsultieren Sie die offizielle Dokumentation.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/SystemManagementGroup(["System Management"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ls("List Containers") docker/ContainerOperationsGroup -.-> docker/logs("View Container Logs") docker/ImageOperationsGroup -.-> docker/push("Push Image to Repository") docker/ImageOperationsGroup -.-> docker/images("List Images") docker/SystemManagementGroup -.-> docker/prune("Remove Unused Docker Objects") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/run -.-> lab-148983{{"Wertschöpfung mit benutzerdefinierten Docker-Images"}} docker/ls -.-> lab-148983{{"Wertschöpfung mit benutzerdefinierten Docker-Images"}} docker/logs -.-> lab-148983{{"Wertschöpfung mit benutzerdefinierten Docker-Images"}} docker/push -.-> lab-148983{{"Wertschöpfung mit benutzerdefinierten Docker-Images"}} docker/images -.-> lab-148983{{"Wertschöpfung mit benutzerdefinierten Docker-Images"}} docker/prune -.-> lab-148983{{"Wertschöpfung mit benutzerdefinierten Docker-Images"}} docker/build -.-> lab-148983{{"Wertschöpfung mit benutzerdefinierten Docker-Images"}} end

Erstellen einer Python-App (ohne Verwendung von Docker)

Führen Sie den folgenden Befehl aus, um eine Datei namens app.py mit einem einfachen Python-Programm zu erstellen. (Kopieren und Einfügen des gesamten Codeblocks)

cd ~/project
echo 'from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "hello world!"

if __name__ == "__main__":
    app.run(host="0.0.0.0")' > app.py

Dies ist eine einfache Python-App, die Flask verwendet, um einen HTTP-Webserver auf Port 5000 zu exportieren (5000 ist der Standardport für Flask). Sorgen Sie sich nicht, wenn Sie nicht sehr vertraut mit Python oder Flask sind, diese Konzepte können auf eine Anwendung in jeder Sprache angewendet werden.

Optional: Wenn Sie Python und pip installiert haben, können Sie diese App lokal ausführen. Wenn nicht, springen Sie zum nächsten Schritt.

$ python3 --version
$ pip3 --version
$ pip3 install flask

$ python3 app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Öffnen Sie die App in einem neuen Browser-Tab mit http://0.0.0.0:5000/.

Flask app browser output

Erstellen und Bauen des Docker-Images

Was passiert, wenn Sie Python lokal nicht installiert haben? Keine Sorge! Denn Sie brauchen es nicht. Einer der Vorteile der Verwendung von Containern ist, dass Sie Python innerhalb Ihrer Container bauen können, ohne Python auf Ihrem Hostcomputer zu installieren.

Erstellen Sie eine Dockerfile, indem Sie folgenden Befehl ausführen. (Kopieren und Einfügen des gesamten Codeblocks)

echo 'FROM python:3.8-alpine
RUN pip install flask
CMD ["python","app.py"]
COPY app.py /app.py' > Dockerfile

Eine Dockerfile listet die Anweisungen auf, die erforderlich sind, um ein Docker-Image zu erstellen. Gehen wir Zeile für Zeile durch die obige Datei.

FROM python:3.8-alpine
Dies ist der Ausgangspunkt für Ihre Dockerfile. Jede Dockerfile muss mit einer FROM-Zeile beginnen, die das Ausgangsimage ist, auf dem Sie Ihre Schichten aufbauen.

In diesem Fall wählen wir die python:3.8-alpine-Basis-Schicht (siehe Dockerfile für python3.8/alpine3.12), da es bereits die Version von Python und pip hat, die wir benötigen, um unsere Anwendung auszuführen.

Die alpine-Version bedeutet, dass es die Alpine Linux-Verteilung verwendet, die erheblich kleiner als viele alternative Linux-Flavoren ist, ca. 8 MB groß, während eine minimale Installation auf der Festplatte ca. 130 MB sein könnte. Ein kleineres Image bedeutet, dass es viel schneller heruntergeladen (deployed) wird, und es hat auch Vorteile für die Sicherheit, da es eine kleinere Angriffsfläche hat. Alpine Linux ist eine Linux-Verteilung, die auf musl und BusyBox basiert.

Wir verwenden hier das "3.8-alpine"-Tag für das Python-Image. Schauen Sie sich die verfügbaren Tags für das offizielle Python-Image auf dem Docker Hub an. Es ist eine bewährte Praxis, einen spezifischen Tag zu verwenden, wenn Sie ein Elternimage erben, um die Änderungen an der Elternabhängigkeit zu kontrollieren. Wenn kein Tag angegeben wird, tritt der "latest"-Tag in Kraft, der als dynamischer Zeiger fungiert, der auf die neueste Version eines Images zeigt.

Aus Sicherheitsgründen ist es sehr wichtig, die Schichten zu verstehen, auf denen Sie Ihr Docker-Image aufbauen. Aus diesem Grund wird dringend empfohlen, nur "offizielle" Images aus dem docker hub oder nicht-Community-Images aus dem docker-store zu verwenden. Diese Images werden überprüft, um bestimmte Sicherheitsanforderungen zu erfüllen, und haben auch sehr gute Dokumentationen für die Benutzer zu folgen. Sie können weitere Informationen zu diesem Python-Basisimage, sowie allen anderen Images, die Sie verwenden können, auf dem docker hub finden.

Für eine komplexere Anwendung können Sie möglicherweise die Verwendung eines FROM-Images benötigen, das höher in der Kette steht. Beispielsweise beginnt die Eltern-Dockerfile für unsere Python-Anwendung mit FROM alpine, und gibt dann eine Reihe von CMD- und RUN-Anweisungen für das Image an. Wenn Sie eine feinere Kontrolle benötigen, können Sie mit FROM alpine (oder einer anderen Verteilung) beginnen und diese Schritte selbst ausführen. Um zu beginnen, empfehle ich jedoch, ein offizielles Image zu verwenden, das Ihren Anforderungen möglichst genau entspricht.

RUN pip install flask
Der RUN-Befehl führt die erforderlichen Befehle aus, um Ihr Image für Ihre Anwendung einzurichten, wie z. B. das Installieren von Paketen, das Bearbeiten von Dateien oder das Ändern von Dateiberechtigungen. In diesem Fall installieren wir flask. Die RUN-Befehle werden zur Build-Zeit ausgeführt und werden zu den Schichten Ihres Images hinzugefügt.

CMD ["python","app.py"]
CMD ist der Befehl, der ausgeführt wird, wenn Sie einen Container starten. Hier verwenden wir CMD, um unsere Python-Anwendung auszuführen.

Es kann nur ein CMD pro Dockerfile geben. Wenn Sie mehr als einen CMD angeben, wird der letzte CMD wirksam. Die Eltern python:3.8-alpine gibt auch einen CMD (CMD python3) an. Sie können die Dockerfile für das offizielle python:alpine-Image hier finden.

Sie können das offizielle Python-Image direkt verwenden, um Python-Skripte auszuführen, ohne Python auf Ihrem Host zu installieren. Heute erstellen wir jedoch ein benutzerdefiniertes Image, um unsere Quelle zu integrieren, damit wir ein Image mit unserer Anwendung erstellen und es an andere Umgebungen weitergeben können.

COPY app.py /app.py
Dies kopiert die app.py im lokalen Verzeichnis (wo Sie docker image build ausführen werden) in eine neue Schicht des Images. Diese Anweisung ist die letzte Zeile in der Dockerfile. Schichten, die häufig geändert werden, wie das Kopieren von Quellcode in das Image, sollten am Ende der Datei platziert werden, um vollkommen von der Docker-Schichtcache zu profitieren. Dies ermöglicht es uns, die Neuerstellung von Schichten zu vermeiden, die anderweitig gecacht werden könnten. Wenn beispielsweise eine Änderung in der FROM-Anweisung erfolgt, wird der Cache für alle nachfolgenden Schichten dieses Images ungültig. Wir werden dies später in diesem Lab demonstrieren.

Es scheint gegen die Intuition zu verlaufen, dies nach der CMD ["python","app.py"]-Zeile zu platzieren. Denken Sie daran, die CMD-Zeile wird erst beim Starten des Containers ausgeführt, so dass wir hier keinen file not found-Fehler erhalten.

Und so haben Sie es: eine sehr einfache Dockerfile. Eine vollständige Liste der Befehle, die Sie in eine Dockerfile einfügen können, finden Sie hier. Jetzt, da wir unsere Dockerfile definiert haben, verwenden wir es, um unser benutzerdefiniertes Docker-Image zu erstellen.

Bauen Sie das Docker-Image.

Geben Sie -t ein, um Ihr Image als python-hello-world zu benennen.

docker image build -t python-hello-world.

Vergewissern Sie sich, dass Ihr Image in Ihrer Imageliste angezeigt wird.

docker image ls

Hinweis: Ihr Basisimage python:3.8-alpine ist ebenfalls in Ihrer Liste.

Sie können einen History-Befehl ausführen, um die Geschichte eines Images und seiner Schichten anzuzeigen,

docker history python-hello-world
docker history python:3.8-alpine

Ausführen des Docker-Images

Jetzt, da Sie das Image gebaut haben, können Sie es ausführen, um zu überprüfen, ob es funktioniert.

Führen Sie das Docker-Image aus

docker run -p 5001:5000 -d python-hello-world

Das -p-Flag bildet einen Port, der innerhalb des Containers läuft, auf Ihren Host ab. In diesem Fall bilden wir den Python-Anwendung, die auf Port 5000 innerhalb des Containers läuft, auf Port 5001 Ihres Hosts ab. Beachten Sie, dass, wenn Port 5001 bereits von einer anderen Anwendung auf Ihrem Host verwendet wird, Sie möglicherweise 5001 durch einen anderen Wert wie 5002 ersetzen müssen.

Navigieren Sie zum Tab PORTS im Terminalfenster und klicken Sie auf den Link, um die App in einem neuen Browser-Tab zu öffnen.

Terminal ports tab link

Führen Sie in einem Terminal curl localhost:5001 aus, was hello world! zurückgibt.

Überprüfen Sie die Logausgabe des Containers.

Wenn Sie die Logs Ihrer Anwendung sehen möchten, können Sie den Befehl docker container logs verwenden. Standardmäßig druckt docker container logs die Ausgabe aus, die von Ihrer Anwendung an die Standardausgabe gesendet wird. Verwenden Sie docker container ls, um die ID Ihres laufenden Containers zu finden.

labex:project/ $ docker container ls
CONTAINER ID   IMAGE                COMMAND           CREATED         STATUS         PORTS                                       NAMES
52df977e5541   python-hello-world   "python app.py"   2 minutes ago   Up 2 minutes   0.0.0.0:5001->5000/tcp, :::5001->5000/tcp   heuristic_lamport
labex:project/ $ docker container logs 52df977e5541
 * Serving Flask app 'app'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://172.17.0.2:5000
Press CTRL+C to quit
172.17.0.1 - - [23/Jan/2024 02:43:10] "GET / HTTP/1.1" 200 -
172.17.0.1 - - [23/Jan/2024 02:43:10] "GET /favicon.ico HTTP/1.1" 404 -

Die Dockerfile ist die Methode, um reproduzierbare Builds für Ihre Anwendung zu erstellen. Ein üblicher Workflow besteht darin, dass Ihre CI/CD-Automatisierung docker image build als Teil ihres Buildprozesses ausführt. Sobald die Bilder gebaut sind, werden sie an einen zentralen Registrierungsdienst gesendet, von dem alle Umgebungen (wie eine Testumgebung), die Instanzen dieser Anwendung ausführen müssen, darauf zugreifen können. Im nächsten Schritt werden wir unser benutzerdefiniertes Image in den öffentlichen Docker-Registrydienst: den Docker Hub pushen, wo es von anderen Entwicklern und Betreibern verwendet werden kann.

Push to a Central Registry

Navigieren Sie zu Docker Hub und erstellen Sie ein Konto, wenn Sie es noch nicht getan haben. Alternativ können Sie auch https://quay.io verwenden, zum Beispiel.

Für dieses Lab verwenden wir den Docker Hub als unseren zentralen Registrierungsdienst. Der Docker Hub ist ein kostenloser Dienst, um öffentlich verfügbare Bilder zu speichern, oder Sie können bezahlen, um private Bilder zu speichern. Gehen Sie zur Docker Hub-Website und erstellen Sie ein kostenloses Konto.

Die meisten Organisationen, die stark Docker verwenden, werden intern ihren eigenen Registrierungsdienst einrichten. Um die Dinge zu vereinfachen, verwenden wir den Docker Hub, aber die folgenden Konzepte gelten für jeden Registrierungsdienst.

Anmeldung

Sie können sich bei Ihrem Imagerregistrierungskonto anmelden, indem Sie docker login in Ihrem Terminal eingeben, oder wenn Sie Podman verwenden, geben Sie podman login ein.

labex:project/ $ export DOCKERHUB_USERNAME=<your_docker_username>
labex:project/ $ docker login docker.io -u $DOCKERHUB_USERNAME
Password:
WARNING! Your password will be stored unencrypted in /home/labex/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Bezeichnen Sie Ihr Image mit Ihrem Benutzernamen

Die Docker Hub-Namenskonvention besteht darin, Ihr Image mit [dockerhub Benutzername]/[Image Name] zu bezeichnen. Dazu werden wir unser zuvor erstelltes Image python-hello-world so bezeichnen, dass es diesem Format entspricht.

docker tag python-hello-world $DOCKERHUB_USERNAME/python-hello-world

Pushen Sie Ihr Image an den Registrierungsdienst

Sobald wir ein richtig bezeichnetes Image haben, können wir den Befehl docker push verwenden, um unser Image an den Docker Hub-Registrierungsdienst zu pushen.

docker push $DOCKERHUB_USERNAME/python-hello-world

Überprüfen Sie Ihr Image im Browser auf dem Docker Hub

Navigieren Sie zu Docker Hub und wechseln Sie zu Ihrem Profil, um Ihr neu hochgeladenes Image unter https://hub.docker.com/repository/docker/<dockerhub-username>/python-hello-world zu sehen.

Jetzt, da Ihr Image auf dem Docker Hub ist, können andere Entwickler und Betreiber den Befehl docker pull verwenden, um Ihr Image in andere Umgebungen bereitzustellen.

Hinweis: Docker-Images enthalten alle Abhängigkeiten, die erforderlich sind, um eine Anwendung innerhalb des Images auszuführen. Dies ist nützlich, da wir keine Umgebungsabweichungen (Versionsunterschiede) mehr berücksichtigen müssen, wenn wir von Abhängigkeiten abhängen, die auf jeder Umgebung installiert sind, auf die wir bereitstellen. Wir müssen auch keine zusätzlichen Schritte durchführen, um diese Umgebungen bereitzustellen. Ein einziger Schritt: Installieren Sie Docker, und Sie sind fertig.

Deploying a Change

Die "Hello World!"-Anwendung wird überbewertet. Lassen Sie uns die App aktualisieren, sodass sie stattdessen "Hello Beautiful World!" sagt.

Update app.py

Ersetzen Sie die Zeichenfolge "Hello World" durch "Hello Beautiful World!" in app.py. Sie können die Datei mit dem folgenden Befehl aktualisieren. (Kopieren und Einfügen des gesamten Codeblocks)

echo 'from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "hello beautiful world!"

if __name__ == "__main__":
    app.run(host="0.0.0.0")' > app.py

Rebuild and Push Your Image

Jetzt, da Ihre App aktualisiert ist, müssen Sie die obigen Schritte wiederholen, um Ihre App neu zu bauen und sie an den Docker Hub-Registrierungsdienst zu pushen.

Zuerst bauen Sie erneut, diesmal verwenden Sie Ihren Docker Hub-Benutzernamen im Build-Befehl:

docker image build -t $DOCKERHUB_USERNAME/python-hello-world.

Beachten Sie die "Using cache" für Schritte 1-3. Diese Schichten des Docker-Images wurden bereits gebaut, und docker image build wird diese Schichten aus dem Cache verwenden, anstatt sie erneut zu bauen.

docker push $DOCKERHUB_USERNAME/python-hello-world

Es gibt auch einen Caching-Mechanismus für das Pushen von Schichten. Der Docker Hub hat bereits alle Schichten außer einer aus einem früheren Push, daher pusht er nur die eine geänderte Schicht.

Wenn Sie eine Schicht ändern, müssen alle darauf aufgebauten Schichten erneut gebaut werden. Jede Zeile in einer Dockerfile baut eine neue Schicht auf, die auf der Schicht basiert, die aus den Zeilen zuvor erstellt wurde. Deshalb ist die Reihenfolge der Zeilen in unserer Dockerfile wichtig. Wir haben unsere Dockerfile optimiert, sodass die Schicht, die am wahrscheinlichsten geändert wird (COPY app.py /app.py), die letzte Zeile der Dockerfile ist. Im Allgemeinen ändert sich für eine Anwendung Ihr Code am häufigsten. Diese Optimierung ist besonders wichtig für CI/CD-Prozesse, bei denen Sie möchten, dass Ihre Automatisierung so schnell wie möglich läuft.

Understanding Image Layers

Eine der wichtigsten Designmerkmale von Docker ist die Verwendung des Union-Dateisystems.

Betrachten Sie die Dockerfile, die wir zuvor erstellt haben:

FROM python:3.8-alpine
RUN pip install flask
CMD ["python","app.py"]
COPY app.py /app.py

Jede dieser Zeilen ist eine Schicht. Jede Schicht enthält nur die Änderungen, Differenzen oder Änderungen gegenüber den vorherigen Schichten. Um diese Schichten zu einem einzelnen laufenden Container zusammenzufügen, verwendet Docker das Union-Dateisystem, um die Schichten transparent zu überlagern und in einer einzigen Ansicht zu kombinieren.

Jede Schicht des Images ist schreibgeschützt, mit Ausnahme der obersten Schicht, die für den laufenden Container erstellt wird. Die schreibende Container-Schicht implementiert das "Copy-on-Write"-Verfahren, was bedeutet, dass Dateien, die in den unteren Image-Schichten gespeichert sind, nur dann in die schreibende Container-Schicht kopiert werden, wenn Änderungen an diesen Dateien vorgenommen werden. Die Änderungen werden dann in der laufenden Container-Schicht gespeichert. Die "Copy-on-Write"-Funktion ist sehr schnell und hat in fast allen Fällen keinen merklichen Effekt auf die Leistung. Sie können überprüfen, welche Dateien in die Containerebene kopiert wurden, mit dem Befehl docker diff. Weitere Informationen über die Verwendung von docker diff finden Sie hier.

understanding image layers

Da die Image-Schichten schreibgeschützt sind, können sie von Images und laufenden Containern geteilt werden. Beispielsweise würde das Erstellen einer neuen Python-App mit ihrer eigenen Dockerfile mit ähnlichen Basis-Schichten alle gemeinsamen Schichten mit der ersten Python-App teilen.

FROM python:3.8-alpine
RUN pip install flask
CMD ["python","app2.py"]
COPY app2.py /app2.py
understanding image layers

Sie können auch die Teilung von Schichten erleben, wenn Sie mehrere Container aus dem gleichen Image starten. Da die Container die gleichen schreibgeschützten Schichten verwenden, können Sie sich vorstellen, dass das Starten von Containern sehr schnell ist und einen sehr geringen Speicherbedarf auf dem Host hat.

Sie werden möglicherweise bemerken, dass es doppelte Zeilen in dieser Dockerfile und der Dockerfile gibt, die Sie zu Beginn dieses Labs erstellt haben. Obwohl dies ein sehr einfaches Beispiel ist, können Sie die gemeinsamen Zeilen beider Dockerfiles in eine "Basis"-Dockerfile ziehen, auf die Sie dann in jeder Ihrer Kind-Dockerfiles mit dem FROM-Befehl verweisen können.

Die Image-Schichtung ermöglicht den Docker-Caching-Mechanismus für Builds und Pushes. Beispielsweise zeigt die Ausgabe Ihres letzten docker push an, dass einige der Schichten Ihres Images bereits auf dem Docker Hub existieren.

$ docker push $DOCKERHUB_USERNAME/python-hello-world

Um genauer auf die Schichten zu schauen, können Sie den Befehl docker image history des Python-Images verwenden, das wir erstellt haben.

$ docker image history python-hello-world

Jede Zeile stellt eine Schicht des Images dar. Sie werden feststellen, dass die obersten Zeilen mit Ihrer erstellten Dockerfile übereinstimmen und die Zeilen darunter aus dem übergeordneten Python-Image stammen. Machen Sie sich keine Sorgen um die "<missing>"-Tags. Dies sind immer noch normale Schichten; sie haben nur keine ID von dem Docker-System erhalten.

Clean up

Das Abschluss dieses Labs führt zu einer Reihe von laufenden Containern auf Ihrem Host. Lassen Sie uns diese aufräumen.

Führen Sie docker container stop [container id] für jeden laufenden Container aus

Zunächst erhalten Sie eine Liste der laufenden Container mit docker container ls.

$ docker container ls

Führen Sie dann den Befehl für jeden Container in der Liste aus.

$ docker container stop <container_id>

Entfernen Sie die gestoppten Container

docker system prune ist ein wirklich praktischer Befehl, um Ihr System aufzuräumen. Er wird alle gestoppten Container, nicht genutzte Volumes und Netze sowie hängende Bilder entfernen.

$ docker system prune
WARNING! This will remove:
- all stopped containers
- all volumes not used by at least one container
- all networks not used by at least one container
- all dangling images
Are you sure you want to continue? [y/N] y
Deleted Containers:
0b2ba61df37fb4038d9ae5d145740c63c2c211ae2729fc27dc01b82b5aaafa26

Total reclaimed space: 300.3kB

Summary

In diesem Lab haben Sie begonnen, Wert zu schaffen, indem Sie Ihre eigenen benutzerdefinierten Docker-Container erstellt haben.

Wichtige Erkenntnisse:

  • Die Dockerfile ist die Methode, um reproduzierbare Builds für Ihre Anwendung zu erstellen und um Ihre Anwendung mit Docker in die CI/CD-Pipeline zu integrieren.
  • Docker-Images können in allen Ihren Umgebungen über einen zentralen Registrierungsdienst zur Verfügung gestellt werden. Der Docker Hub ist ein Beispiel für einen Registrierungsdienst, aber Sie können auch Ihren eigenen Registrierungsdienst auf Servern, die Sie steuern, bereitstellen.
  • Docker-Images enthalten alle Abhängigkeiten, die erforderlich sind, um eine Anwendung innerhalb des Images auszuführen. Dies ist nützlich, da wir keine Umgebungsabweichungen (Versionsunterschiede) mehr berücksichtigen müssen, wenn wir von Abhängigkeiten abhängen, die auf jeder Umgebung installiert sind, auf die wir bereitstellen.
  • Docker nutzt das Union-Dateisystem und "Copy on Write", um Schichten von Images zu wiederverwenden. Dies verringert den Speicherbedarf für Images und erhöht die Leistung beim Start von Containern erheblich.
  • Image-Schichten werden vom Docker-Build- und -Push-System zwischengespeichert. Es ist nicht erforderlich, Image-Schichten neu zu bauen oder erneut zu pushen, die bereits auf dem gewünschten System vorhanden sind.
  • Jede Zeile in einer Dockerfile erstellt eine neue Schicht, und aufgrund des Schichtcaches sollten die Zeilen, die häufiger geändert werden (z.B. Hinzufügen von Quellcode zu einem Image), am Ende der Datei aufgelistet werden.