Wenn Sie schon einmal beim Start einen oder zwei Befehle in Ihrem Docker-Container ausführen mussten, ist dieses Tutorial genau das Richtige für Sie. Mit dem Dockerfile ENTRYPOINT
und CMD
Anweisungen können Sie so viele Startbefehle ausführen, wie Sie möchten.
In diesem Tutorial erfahren Sie, wie Sie den ENTRYPOINT
verwenden und CMD
Anweisungen zum Ausführen von Startbefehlen in einer Docker-Datei und zum Verstehen der Unterschiede zwischen ihnen.
Voraussetzungen
Da es sich bei diesem Tutorial um eine praktische Demonstration handelt, vergewissern Sie sich, dass Folgendes vorhanden ist:
- In diesem Tutorial wurde ein Windows 10-PC – Windows 10 v10.0.19042 verwendet.
- Docker Desktop – Dieses Tutorial verwendet Docker Desktop v3.3.1.
Erstellen eines Dockerfiles
Bevor Sie Docker-Container-Startbefehle ausführen können, müssen Sie zunächst eine Dockerfile erstellen. Ein Dockerfile ist ein Textdokument, das eine Liste von Befehlen zum Erstellen von Containern und Docker-Images enthält und bestimmt, wie ein Docker-Image erstellt wird.
1. Öffnen Sie zunächst PowerShell als Administrator.
2. Erstellen Sie einen neuen Ordner zum Speichern der Docker-Datei und aller zugehörigen Dateien, die in diesem Tutorial verwendet werden, 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 folgendem Befehl.
cd > Dockerfile
Alternativ können Sie eine Docker-Datei 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 ein
FROM ubuntu:20.04
Sie haben jetzt ein baldiges Dockerfile erstellt!
Erstellen eines Docker-Images
Nachdem Sie Ihr Dockerfile erstellt haben, müssen Sie ein Docker-Image erstellen, um die Befehle auszuführen, die in Ihren Dockerfile ENTRYPOINT- und CMD-Anweisungen geschrieben sind. Eine Möglichkeit, ein Image zu erstellen, ist die Verwendung von build
Befehl.
Im ~/docker Verzeichnis, führen Sie den folgenden Befehl aus. Der folgende Befehl erstellt ein Docker-Image namens demo (-t demo
) aus dem Dockerfile in ~/docker durch Angabe des aktuellen Arbeitsverzeichnisses (.
).
docker build -t demo .
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 run
auf Befehl zum Erstellen einer beschreibbaren Containerschicht über dem Docker-Image (demo
). Das folgende Beispiel verwendet den -it
Parameter, um sich interaktiv mit dem Container zu verbinden, damit Sie die Beispielausgabe sehen können.
docker run -it demo
Exec vs. Shell-Formular
Wenn Sie anfangen, mit einer Docker-Datei zu arbeiten und herausfinden, wie Startbefehle ausgeführt werden, stoßen Sie möglicherweise auf zwei verschiedene Methoden zum Definieren dieser Befehle. Jede Methode ruft Befehle auf, tut dies jedoch etwas anders.
Wenn Docker Befehle ausführt, kann es dies direkt mit dem Namen exec
tun oder gehen Sie durch die Shell des Containers (/bin/sh -c
unter Linux oder cmd /S /C
unter Windows) namens shell
.
Sie werden Befehle bemerken, die über exec
ausgeführt werden eine Anweisung haben, gefolgt von den auszuführenden ausführbaren Dateien, gefolgt von einem oder mehreren Befehlszeilenargumenten, wie unten gezeigt.
ENTRYPOINT ["executables", "parameter1", "parameter2", ...]
CMD ["executables", "parameter1", "parameter2:, ...]
Schreiben von Befehlen in shell
form hingegen erfordert es nicht, Befehle in eckige Klammern zu setzen, wie unten gezeigt.
ENTRYPOINT <command> "parameter1"
CMD <command> "parameter1"
Wenn Sie kein Argument für
CMD
angeben , Docker führt den Befehl immer in exec-Form aus, z.CMD <command>
.
Wenn Sie gerade erst anfangen, ist die Unterscheidung zwischen diesen beiden Befehlsaufrufen nicht allzu wichtig, aber wenn Sie fortgeschrittener werden, werden Sie bald die Vor- und Nachteile beider erkennen.
Startbefehle ausführen
Lassen Sie uns nun in das Kernstück dieses Tutorials einsteigen und uns die Hände schmutzig machen, indem wir einige Beispiele für die Ausführung von Startbefehlen innerhalb eines Dockerfile-ENTRYPOINT
durchgehen und CMD-Anweisungen.
1. Öffnen Sie die zuvor erstellte Docker-Datei in Ihrem bevorzugten Texteditor.
2. Kopieren Sie den Dockerfile-Beispielinhalt, fügen Sie ihn wie unten gezeigt in Ihre Dockerfile ein und speichern Sie ihn.
Dieses Dockerfile erstellt eine Ebene mit ubuntu:20.04
als Grundbild. Anschließend weist es Docker an, das echo
aufzurufen Befehl, der ihm den Hello world
übergibt Argument sowohl für das Dockerfile CMD
und ENTRYPOINT
Anweisungen mit exec
und shell
form.
FROM ubuntu:20.04
# CMD Instruction
CMD ["echo", "Hello world"] # Exec Form
CMD echo "Hello world" # Shell Form
# ENTRYPOINT Instruction
ENTRYPOINT ["echo", "Hello world"] # Exec Form
ENTRYPOINT echo "Hello world" # Shell Form
3. Im ~/docker erstellen Sie das neue Image, indem Sie docker build
ausführen und nenne es demo
. Der folgende Befehl tags das Bild als demo
und sucht nach einem Dockerfile im aktuellen Arbeitsverzeichnis (.
).
docker build -t demo .
4. Führen Sie nun einen Container mit dem Image aus und führen Sie dann einen Docker-Container basierend auf dem zuvor erstellten Docker-Image aus. Sie sehen nun, dass der Container Hello world
zurückgibt die von der CMD
kam Anweisung in der Dockerfile.
docker run -it demo
Variablen in einem Dockerfile verwenden
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 verfügbar gemacht. Anstatt Befehlsargumente statisch zuzuweisen, können Sie diese Argumente erfassen und an Befehle mit Variablen übergeben.
Sie können Dockerfile-Variablen nur in
shell
verwenden form. Docker unterstützt keine Variablen in Befehlen, die überexec
aufgerufen werden Formular.
Öffnen Sie das Dockerfile erneut in Ihrem bevorzugten Texteditor, ersetzen Sie alles darin durch die folgende Befehlsfolge und speichern Sie es.
Sie werden feststellen, dass das Dockerfile diesmal Umgebungsvariablen verwendet und mit ENV
angezeigt wird . Im folgenden Beispiel definiert das Dockerfile eine Umgebungsvariable namens name
mit einem Wert von friend
. Einmal erstellt, wird diese Umgebungsvariable dann über $name
referenziert .
Wenn Docker einen Container basierend auf dieser Docker-Datei ausführt, ruft es das echo
auf Befehl und übergeben Sie das Argument von Welcome, friend
.
FROM ubuntu:20.04
ENV name friend
CMD echo "Welcome, $name"
# or
## ENTRYPOINT echo "Welcome, $name"
Erstellen Sie nun das Docker-Image und führen Sie den Container erneut aus, wobei Sie optional einen Tag-Namen von shellform
angeben . Sie werden feststellen, dass Docker das echo
aufgerufen hat Befehl und gab die erwartete Ausgabe zurück.
Kombinieren von Dockerfile-ENTRYPOINT- und CMD-Anweisungen
Die meiste Zeit werden Sie Startbefehle entweder in CMD- oder ENTRYPOINT-Befehlen aufrufen. Schließlich können Sie mit jeder Methode so viele Befehle aufrufen, wie Sie möchten. Sie können aber auch einen einzelnen Befehl aufrufen und mit beiden Anweisungen „darauf aufbauen“.
Aufbauend auf den vorherigen Beispielen haben Sie vielleicht eine Dockerfile, die wie das folgende Beispiel aussieht. Wenn Sie ein Image erstellen und einen Container von diesem Image ausführen, würde Docker das echo
aufrufen Befehl und geben Sie Hello
zurück .
FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
Vielleicht haben Sie ein weiteres Argument, das Sie an echo
übergeben möchten Befehl, aber nicht sofort. Vielleicht möchten Sie das weiter unten in der Dockerfile tun. Durch Aufruf der CMD
Anweisung ohne Befehl, können Sie dies tun.
Wenn Sie einen Befehl angeben, der über den
ENTRYPOINT
ausgeführt werden soll Anweisung gefolgt vonCMD
Anweisung übernimmt Docker automatisch den anCMD
übergebenen Wert ist ein Argument; kein Befehl.
Fügen Sie nun eine CMD
hinzu Anweisungsreferenz ohne Befehl, nur ein Argument namens world
, wie unten gezeigt.
FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
CMD ["world"]
Kombinierende Anweisungen sollten aufgrund ihres „Array-ähnlichen“ Verhaltens immer in Exec-Form geschrieben werden, indem Werte einzeln durch Kommas getrennt und nicht alle in einer Zeichenfolge angegeben werden.
Nachdem Sie das Image erstellt und den Container aus dem Image ausgeführt haben, können Sie sehen, dass anstelle von zwei Ausgabezeilen (Hello
und world
), Docker gibt nur einen zurück, was nur ein einzelnes echo
bedeutet Befehlsaufruf.
Fazit
Sie sollten jetzt ein gutes Verständnis dafür haben, wie Docker-Container-Startbefehle sowohl über CMD
ausgeführt werden und ENTRYPOINT
Dockerfile-Anweisungen. Jede Anweisung ist etwas anders, erfüllt aber die gleiche Aufgabe und kann sogar zusammen verwendet werden.
Können Sie sich ein Szenario vorstellen, in dem Sie lieber CMD
verwenden würden über ENTRYPOINT
einen Startbefehl ausführen?