Unterschied zwischen CMD und ENTRYPOINT in Docker

Isaac Tony 23 August 2022
  1. das CMD-Kommando im Docker
  2. den ENTRYPOINT-Befehl im Docker
  3. Fazit
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.

Autor: Isaac Tony
Isaac Tony avatar Isaac Tony avatar

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

Verwandter Artikel - Docker Command