Verwendung der Dockerfile ENTRYPOINT- und CMD-Anweisungen

Wenn Sie jemals ein oder zwei Befehle beim Start Ihres Docker-Containers ausführen mussten, ist dieses Tutorial für Sie. Mithilfe der Dockerfile ENTRYPOINT– und CMD-Anweisungen können Sie so viele Startbefehle ausführen, wie Sie möchten.

In diesem Tutorial erfahren Sie, wie Sie die ENTRYPOINT– und CMD-Anweisungen verwenden, um Startbefehle in einer Dockerfile auszuführen, und verstehen die Unterschiede zwischen ihnen.

Voraussetzungen

Da dieses Tutorial eine praktische Demonstration sein wird, stellen Sie sicher, dass Sie folgendes bereit haben:

  • A Windows 10 PC – Windows 10 v10.0.19042 was used in this tutorial.
  • Docker Desktop – Dieses Tutorial verwendet Docker Desktop v3.3.1.

Erstellen einer Dockerfile

Bevor Sie Docker-Container-Startbefehle ausführen können, müssen Sie zunächst eine Dockerfile erstellen. Eine Dockerfile ist ein Textdokument, das eine Liste von Befehlen zum Erstellen von Containern, Docker-Images enthält und festlegt, wie ein Docker-Image erstellt wird.

1. Öffnen Sie zuerst PowerShell als Administrator.

2. Erstellen Sie einen neuen Ordner, um das Dockerfile und alle zugehörigen Dateien zu speichern, die dieses Tutorial verwenden wird, und wechseln Sie in dieses Verzeichnis. Dieses Tutorial verwendet ~/docker.

mkdir ~/docker
cd docker

3. Erstellen Sie nun eine leere Textdatei mit dem Namen Dockerfile mit dem folgenden Befehl.

cd > Dockerfile

Alternativ können Sie ein Dockerfile mit dem folgenden Befehl erstellen, wenn Sie Linux oder Mac OS verwenden.

touch Dockerfile

4. Fügen Sie schließlich den folgenden Inhalt in das Dockerfile

FROM ubuntu:20.04

Sie haben nun ein baldiges Dockerfile erstellt!

Erstellen eines Docker-Images

Jetzt, da Sie Ihr Dockerfile erstellt haben, müssen Sie ein Docker-Image erstellen, um die in Ihren Dockerfile-ENTRYPOINT- und CMD-Anweisungen geschriebenen Befehle auszuführen. Eine Möglichkeit, ein Bild zu erstellen, besteht darin, den build-Befehl zu verwenden.

Während Sie sich im Verzeichnis ~/docker befinden, führen Sie den folgenden Befehl aus. Der folgende Befehl erstellt ein Docker-Image namens demo (-t demo) aus dem Dockerfile in ~/docker, indem das aktuelle Arbeitsverzeichnis angegeben wird (.).

docker build -t demo .
Building a Docker Image

Ausführen eines Docker-Containers

Nachdem Sie das Docker-Image erstellt haben, benötigen Sie einen Container, um das Docker-Image auszuführen, das die Befehle aus den Dockerfile-ENTRYPOINT- und CMD-Anweisungen ausführt.

Um einen Docker-Container auszuführen, rufen Sie den Befehl run auf, um eine beschreibbare Container-Schicht über dem Docker-Image (demo) zu erstellen. Das unten stehende Beispiel verwendet den Parameter -it, um interaktiv mit dem Container zu verbinden, damit Sie die Beispelausgabe sehen können.

docker run -it demo
Running a Docker Container

Exec vs. Shell Form

Wenn Sie mit einem Dockerfile arbeiten und herausfinden, wie Sie Startbefehle ausführen können, stoßen Sie möglicherweise auf zwei verschiedene Methoden zur Definition dieser Befehle. Jede Methode ruft Befehle auf, macht dies jedoch etwas anders.

Wenn Docker Befehle ausführt, kann es dies direkt mit exec aufrufen oder durch die Shell des Containers gehen (/bin/sh -c unter Linux oder cmd /S /C unter Windows), genannt shell.

Sie werden feststellen, dass Befehle, die über exec ausgeführt werden, eine Anweisung gefolgt von den auszuführenden Ausführbaren und ein oder mehrere Befehlszeilenargumente haben, wie unten gezeigt.

ENTRYPOINT ["executables", "parameter1", "parameter2", ...]
CMD ["executables", "parameter1", "parameter2:, ...]

Das Schreiben von Befehlen in shell-Form erfordert hingegen nicht, Befehle in eckige Klammern zu setzen, wie unten gezeigt.

ENTRYPOINT <command> "parameter1"
CMD <command> "parameter1"

Wenn Sie kein Argument für CMD angeben, wird Docker den Befehl immer im exec-Format ausführen, z.B. CMD <Befehl>.

Wenn Sie gerade erst anfangen, spielt es zunächst keine große Rolle, zwischen diesen beiden Befehlsaufrufen zu unterscheiden, aber wenn Sie fortgeschrittener werden, werden Sie bald Vor- und Nachteile jeder Methode erkennen.

Ausführung von Startbefehlen

Lassen Sie uns jetzt zum Kern dieses Tutorials übergehen und Ihre Hände schmutzig machen, indem Sie einige Beispiele für das Ausführen von Startbefehlen innerhalb eines Dockerfiles `ENTRYPOINT` und `CMD`-Anweisungen durchgehen.

1. Öffnen Sie das Dockerfile, das Sie zuvor in Ihrem bevorzugten Texteditor erstellt haben.

2. Kopieren Sie den Beispiel-Dockerfile-Inhalt in Ihr Dockerfile, wie unten gezeigt, und speichern Sie ihn ab.

Dieses Dockerfile erstellt eine Ebene unter Verwendung des Basisimages `ubuntu:20.04`. Anschließend teilt Docker mit, den Befehl `echo` aufzurufen und ihm das Argument `Hello world` sowohl für die Dockerfile `CMD`- als auch `ENTRYPOINT`-Anweisungen unter Verwendung der `exec`- und `shell`-Form zu übergeben.

FROM ubuntu:20.04
# CMD Anweisung
CMD ["echo", "Hello world"] # Exec Form
CMD echo "Hello world"      # Shell Form
# ENTRYPOINT Anweisung
ENTRYPOINT ["echo", "Hello world"] # Exec Form
ENTRYPOINT echo "Hello world"      # Shell Form

3. Während Sie sich im Verzeichnis `~/docker` befinden, erstellen Sie das neue Image, indem Sie docker build ausführen und nennen Sie es `demo`. Der folgende Befehl markiert das Image als `demo` und sucht nach einem Dockerfile im aktuellen Arbeitsverzeichnis (`.`).

docker build -t demo .
Building a Docker image with docker build

4. Führen Sie nun einen Container mit dem Image aus und starten Sie dann einen Docker-Container basierend auf dem zuvor erstellten Docker-Image. Sie werden nun sehen, dass der Container `Hello world` zurückgibt, der aus der `CMD`-Anweisung stammt, die im Dockerfile angegeben wurde.

docker run -it demo
Running a Docker container with docker run

Verwendung von Variablen in einem Dockerfile

Manchmal kennen Sie möglicherweise nicht die genauen Befehlszeilenargumente, die Sie im Voraus an den Befehl übergeben müssen. Die Argumente, die Sie an einen Befehl übergeben müssen, werden nur zur Laufzeit angezeigt. Anstatt Befehlsargumente statisch zuzuweisen, können Sie diese Argumente mit Variablen erfassen und an Befehle übergeben.

Sie können Dockerfile-Variablen nur in der shell-Form verwenden. Docker unterstützt keine Variablen in Befehlen, die über die exec-Form aufgerufen werden.

Öffnen Sie die Dockerfile erneut in Ihrem bevorzugten Texteditor, ersetzen Sie alles durch die folgenden Befehle und speichern Sie sie.

Sie werden feststellen, dass die Dockerfile dieses Mal Umgebungsvariablen verwendet und mit ENV angezeigt werden. Im folgenden Beispiel definiert die Dockerfile eine Umgebungsvariable namens name mit einem Wert von friend. Sobald diese Umgebungsvariable erstellt wurde, wird sie über $name referenziert.

Wenn Docker einen Container basierend auf dieser Dockerfile ausführt, wird der echo-Befehl aufgerufen und das Argument Welcome, friend übergeben.

FROM ubuntu:20.04
ENV name friend

CMD echo "Welcome, $name"
# oder
## ENTRYPOINT echo "Willkommen, $name"

Erstellen Sie nun das Docker-Image und führen Sie den Container erneut aus, optional mit einem Tag-Namen von shellform. Sie werden feststellen, dass Docker den echo-Befehl aufgerufen hat und die erwartete Ausgabe zurückgegeben wurde.

Building a Docker Image (shellform) and Running a Docker Container

Kombinieren von Dockerfile ENTRYPOINT und CMD Anweisungen

Die meiste Zeit werden Sie Startbefehle entweder in CMD oder ENTRYPOINT Anweisungen aufrufen. Schließlich können Sie mit jeder Methode so viele Befehle aufrufen, wie Sie möchten. Sie können jedoch auch einen einzelnen Befehl aufrufen und ihn mit beiden Anweisungen „erweitern“.

Basierend auf den vorherigen Beispielen haben Sie möglicherweise ein Dockerfile, das wie das folgende Beispiel aussieht. Wie es ist, wenn Sie ein Image erstellen und einen Container von diesem Image ausführen, würde Docker den Befehl echo aufrufen und Hello zurückgeben.

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]

Vielleicht haben Sie ein anderes Argument, das Sie an den echo-Befehl übergeben möchten, aber nicht sofort. Vielleicht möchten Sie das weiter unten im Dockerfile tun. Indem Sie die CMD-Anweisung ohne Befehl aufrufen, können Sie dies tun.

Wenn Sie über die ENTRYPOINT-Anweisung einen auszuführenden Befehl angeben, gefolgt von der CMD-Anweisung, geht Docker automatisch davon aus, dass der an CMD übergebene Wert ein Argument ist und kein Befehl.

Fügen Sie nun eine CMD-Anweisung hinzu, die keinen Befehl enthält, sondern nur ein Argument mit dem Namen world, wie unten gezeigt.

FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
CMD ["world"]

Die Kombination von Anweisungen sollte immer in exec-Form geschrieben werden, aufgrund ihres „arrayähnlichen“ Verhaltens, Werte einzeln durch Kommas getrennt statt alles in einem String anzugeben.

Nachdem Sie das Image erstellt und den Container aus dem Image ausgeführt haben, können Sie sehen, dass Docker anstelle von zwei Ausgabezeilen (Hello und world) nur eine zurückgibt, was bedeutet, dass nur ein einzelner echo-Befehl aufgerufen wird.

Building a Docker Image (demo3) and Running a Docker Container

Fazit

Du solltest nun ein gutes Verständnis dafür haben, wie man Docker-Container-Startbefehle sowohl über die Dockerfile-Anweisungen CMD als auch ENTRYPOINT ausführt. Jede Anweisung ist etwas anders, erfüllt aber dieselbe Aufgabe und kann sogar zusammen verwendet werden.

Kannst du dir ein Szenario vorstellen, in dem du CMD bevorzugst, um einen Startbefehl auszuführen, anstatt ENTRYPOINT zu verwenden?

Source:
https://adamtheautomator.com/dockerfile-entrypoint/