Unterschied zwischen CMD und ENTRYPOINT in Docker
Docker-Container sind zum Standard geworden, wenn es um die Verwaltung von Software und Abhängigkeiten in unterschiedlichen Umgebungen geht. Sie müssen eine Docker-Datei erstellen, bevor Sie das Container-Image Ihrer Anwendung erstellen, wenn Sie mit echten Anwendungen arbeiten.
Eine Docker-Datei ist einfach ein schreibgeschütztes Textdokument mit einer Reihe von Anweisungen, die beim Zusammenstellen eines Bildes aufgerufen werden. Zu diesen Befehlen gehören RUN
, CMD
und ENTRYPOINT
.
In diesem Artikel werden wir die Verwendung dieser Befehle besprechen. Die meisten Entwickler, die sich wahrscheinlich in der Anfangsphase des Erlernens von Docker befinden, neigen dazu, diese Befehle austauschbar zu verwenden, was Ihnen einige Probleme bereiten kann.
das CMD
-Kommando im Docker
Dieser Befehl gibt eine Anweisung an, die immer dann ausgeführt wird, wenn der Docker-Befehl RUN
ausgeführt wird. Voraussetzung dafür ist allerdings, dass der Docker-Befehl RUN
ohne Angabe von Argumenten ausgeführt wird.
Wenn Argumente angegeben werden, wird dieser Befehl überschrieben. Andererseits wird der Befehl CMD
ausgeführt, wenn keine Befehlszeilenargumente angegeben werden.
Der Befehl CMD
ist nicht zwingend erforderlich, damit Ihr Docker-Container ordnungsgemäß funktioniert, da der Befehl ECHO
zur Laufzeit für denselben Zweck verwendet werden kann. Der Befehl CMD
kann jedoch praktisch sein, wenn bei jedem Start des Containers eine ausführbare Datei ausgeführt wird.
Um zu demonstrieren, wie wir mit dem Befehl CMD
eine ausführbare Datei zur Laufzeit ausführen können, erstellen wir einen einfachen Docker-Container mit einem einfachen Flask-Programm, das eine Nachricht ausgibt. Beachten Sie, dass dies in jeder Sprache repliziert werden kann, nicht unbedingt in Python.
Wir beginnen mit der Erstellung unserer Hauptanwendung, die so einfach wie unten gezeigt sein sollte.
from flask import Flask
app = Flask(__name__)
def hello():
print("Hello, this is a simple Flask application")
hello()
Innerhalb desselben Ordners erstellen wir unser Dockerfile mit dem Befehl touch Dockerfile
.
Das Dockerfile gibt nur das Basis-Image, das Arbeitsverzeichnis und die Pakete an, die installiert werden sollen.
In der letzten Zeile sollten Sie den Befehl CMD
notieren. In diesem Fall verwenden wir den Befehl CMD
, um die Datei app.py
auszuführen, wenn der Container gestartet wird.
# base image
FROM python
# Set your working directory
WORKDIR /var/www/
# Copy the necessary files
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt
# Install the necessary packages
RUN pip install -r /var/www/requirements.txt
# Run the app
CMD python3 app.py
Die requirements.txt
sollte wie unten gezeigt aussehen.
click==8.0.4
Flask==2.0.3
gunicorn==20.1.0
itsdangerous==2.1.0
Jinja2==3.0.3
MarkupSafe==2.1.0
Werkzeug==2.0.3
Jetzt, da wir alles bereit haben, können wir jetzt fortfahren und das Docker-Image erstellen. Zuvor müssen wir sicherstellen, dass wir uns im selben Ordner befinden, in dem unser Programm gespeichert ist.
In unserem Fall gehen wir in den Ordner my-app
, bevor wir das Image erstellen, wie unten gezeigt.
~/my-app$ docker build -t isaactonyloi_image .
Ausgabe:
=> [internal] load build context 0.9s
=> => transferring context: 320B 0.1s
=> [2/5] WORKDIR /var/www/ 5.1s
=> [3/5] COPY ./app.py /var/www/app.py 3.2s
=> [4/5] COPY ./requirements.txt /var/www/requirements.txt 3.2s
=> [5/5] RUN pip install -r /var/www/requirements.txt 53.9s
=> exporting to image 6.9s
=> => exporting layers 5.8s
=> => writing image sha256:5847e4777754d9d576accd929076bfbee633ca71f049ebe1af6e9bae161f3e96 0.1s
=> => naming to docker.io/library/isaactonyloi_image 0.2s
isaac@DESKTOP-HV44HT6:~/my-app$
Wir haben unser Image erfolgreich basierend auf der früheren Docker-Datei erstellt. Das können wir unten verifizieren.
~/my-app$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
isaactonyloi_image latest 5847e4777754 7 minutes ago 929MB
Basierend auf diesem Image können wir schließlich unseren Docker-Container mit dem Docker-Befehl run
erstellen. Beachten Sie auch, dass wir dies tun, ohne Argumente zu übergeben, um den Befehl CMD
auszuführen.
~/my-app$ docker run isaactonyloi_image
Hello, this is a simple Flask application
Abgesehen davon erlaubt uns der CMD
-Befehl auch, Argumente zu erstellen, die zur Laufzeit einfach überschrieben werden können.
Im folgenden Beispiel haben wir Änderungen am Befehl CMD
vorgenommen. Die anderen Dateien bleiben intakt, und wir haben ein neues Image erstellt.
# base image
FROM python
# Set your working directory
WORKDIR /var/www/
# Copy the necessary filesls
COPY ./app.py /var/www/app.py
COPY ./requirements.txt /var/www/requirements.txt
# Install the necessary packages
RUN pip install -r /var/www/requirements.txt
# Run the app
CMD ["echo", "Hello, Developer"]
Hier ist das neue Image, das wir aus unseren Änderungen an der Dockerfile neu erstellt haben.
~/my-app$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
new_image latest 73f323be0d2f 25 minutes ago 929MB
Wir sollten die Meldung unter dem Befehl CMD
erhalten, wenn wir erneut einen neuen Docker-Container erstellen, ohne ein Argument zu übergeben.
isaac@DESKTOP-HV44HT6:~/my-app$ docker run new_image
Hello, Developer
Der Befehl CMD
wird jedoch automatisch überschrieben, wenn wir zur Laufzeit ein Argument übergeben, und das neue Argument sollte Vorrang haben. Daher gibt es uns die Flexibilität, zur Laufzeit neue Argumente hinzuzufügen, wie unten gezeigt.
~/my-app$ docker run new_image hostname
da0a832888cb
Die obige Ausgabe zeigt, dass der Befehl CMD
nicht ausgeführt und durch das neue Hostname-Argument überschrieben wird.
den ENTRYPOINT
-Befehl im Docker
Der Docker-Befehl ENTRYPOINT
hat Ähnlichkeiten mit dem Befehl CMD
, ist aber nicht ganz gleich.
Wenn wir den Befehl CMD
verwenden, können wir ihn leicht überschreiben, indem wir zur Laufzeit Argumente übergeben, aber das ist beim Befehl ENTRYPOINT
nicht der Fall.
Daher kann ENTRYPOINT
verwendet werden, um die Einstiegspunktanweisung zur Laufzeit nicht zu überschreiben.
Wie unten gezeigt, können wir untersuchen, wie dieser Befehl funktioniert, indem wir einfach den Befehl CMD
durch den Befehl ENTRYPOINT
in unserer Dockerfile ersetzen. Wir werden ein neues Image basierend auf unseren Änderungen an der Docker-Datei erstellen.
isaac@DESKTOP-HV44HT6:~/my-app$ docker build -t tonyloi_newimage .
[+] Building 42.7s (10/10) FINISHED
Ausgabe:
=> [internal] load build definition from Dockerfile 2.0s
=> => transferring dockerfile: 365B 0.7s
=> [internal] load .dockerignore 1.6s
=> => transferring context: 2B 0.4s
=> [internal] load metadata for docker.io/library/python:latest 35.4s
=> [1/5] FROM docker.io/library/python@sha256:c90e15c86e2ebe71244a2a51bc7f094554422c159ce309a6faadb6debd5a6df0 0.3s
=> [internal] load build context 1.2s
=> => transferring context: 63B 0.1s
=> CACHED [2/5] WORKDIR /var/www/ 0.0s
=> CACHED [3/5] COPY ./app.py /var/www/app.py 0.0s
=> CACHED [4/5] COPY ./requirements.txt /var/www/requirements.txt 0.0s
=> CACHED [5/5] RUN pip install -r /var/www/requirements.txt 0.0s
=> exporting to image 2.1s
=> => exporting layers 0.0s
=> => writing image sha256:15fb8e4e3ff58ed529b11342bba75b029fd4323beb24aac70ca36b178d04cb34 0.2s
=> => naming to docker.io/library/tonyloi_newimage 0.1s
isaac@DESKTOP-HV44HT6:~/my-app$
Diese Ausgabe ist ein Beweis dafür, dass wir erfolgreich ein neues Image erstellt haben. Jetzt können wir basierend auf diesem Image einen neuen Docker-Container erstellen.
Sie können den Container mit dem Image-Namen oder der Image-ID erstellen, auf die Sie beide mit dem Befehl docker images
zugreifen können. Dadurch werden auch die zuvor erstellten Bilder angezeigt.
~/my-app$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tonyloi_newimage latest 15fb8e4e3ff5 48 minutes ago 929MB
new_image latest 73f323be0d2f 48 minutes ago 929MB
isaactonyloi_image latest 5847e4777754 48 minutes ago 929MB
Wenn wir unseren Docker-Container erstellen, ohne Argumente hinzuzufügen, sollten wir eine Ausgabe wie unten erhalten.
isaac@DESKTOP-HV44HT6:~/my-app$ docker run tonyloi_newimage
Hello, Developer
Wenn wir versuchen, Argumente zu übergeben, wenn wir basierend auf diesem Bild einen weiteren Container erstellen, werden Sie feststellen, dass diese neuen Argumente im Gegensatz zum Befehl CMD
den Befehl ENTRYPOINT
nicht überschreiben.
Wir können dies unten überprüfen.
isaac@DESKTOP-HV44HT6:~/my-app$ docker run tonyloi_newimage Welcome to ADC
Hello, Developer Welcome to ADC
Fazit
Wir können feststellen, dass diese beiden Befehle sehr ähnlich sind; Ihr Unterschied besteht jedoch darin, dass der Befehl CMD
zur Laufzeit überschrieben werden kann, während der Befehl ENTRYPOINT
dies nicht kann.
Außerdem können Situationen die gleichzeitige Verwendung der beiden Befehle rechtfertigen.
Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.
LinkedIn