Keine Werbung mögen? Gehen Werbefrei Heute

Docker ENTRYPOINT im Vergleich zu CMD — Dein Container hat dich belogen

Aktualisiert am

Sie haben in Ihrer Dockerfile ENTRYPOINT und CMD kombiniert, deshalb startete der Container die falsche Anwendung, und jetzt sind Sie hier. Hier ist die vollständige Ausführlichkeit – jede Kombination, der Haken bei Shell und exec-Form, und die Muster, die tatsächlich funktionieren.

Docker ENTRYPOINT vs CMD — Ihr Container hat Sie betrogen 1
ANZEIGE Entfernen?

Der Fehler tritt um 2 Uhr morgens auf. Sie starten Ihren Container und statt Ihrer API-Server erhalten Sie eine Shell-Ausgabe. Oder gar nichts. Oder Ihr Prozess läuft in einer Phantom-Verpackung. sh das verschlingt SIGTERM wie Süßigkeiten — eine graceful Shutdown dauert 10 Sekunden Docker-Warten, bevor es aufgibt und sendet SIGKILL.

Die Schuldige, fast immer: Sie haben verwechselt ENTRYPOINT und CMD. Oder kombiniert sie auf Weise, die Docker stumm akzeptiert — nur nicht so, wie Sie erwartet haben.

CMD: Die Standardfunktion, die ersetzt werden kann

CMD bestimmt, was beim Start eines Containers ausgeführt wird — aber es ist nur ein Vorschlag, kein Regel. Jede Angabe nach dem Bildnamen wird vollständig ersetzt:

FROM ubuntu
CMD ["echo", "hello from CMD"]
$ docker run myimage
hello from CMD

$ docker run myimage echo goodbye
goodbye

Das echo goodbye hat nicht angehängt — es wurde ersetzt. Ihr gesamter CMD ist verschwunden. Dies ist absichtlich: CMD ist das Standardverhalten, nicht das verpflichtende Verhalten. Jeder Laufzeitargument gewinnt.

ENTRYPOINT: Der Teil, der immer ausgeführt wird

ENTRYPOINT bestimmt den auszuführenden Befehl, unabhängig davon. Laufzeitargumente ersetzen ihn nicht — sie werden stattdessen an ihn weitergegeben:

FROM ubuntu
ENTRYPOINT ["echo"]
CMD ["hello"]
$ docker run myimage
hello

$ docker run myimage goodbye
goodbye

$ docker run --entrypoint cat myimage /etc/hostname
mycontainer-abc123

Wenn beide festgelegt sind, ENTRYPOINT ist der auszuführende Befehl und CMD wird seine Standardargumente. Sie können CMD frei überschreiben. Sie können ENTRYPOINT nur dann überschreiben, wenn Sie explizit --entrypoint.

Jede ENTRYPOINT + CMD-Kombination, erklärt

Die Docker-Dokumentation enthält diese Tabelle, aber verweist nicht ausreichend auf die Zeilen, die Ihr Tag verderben:

ENTRYPOINTCMDWas tatsächlich ausgeführt wird
Immer gesetzt für Authentifizierungs-CookiesImmer gesetzt für Authentifizierungs-CookiesFehler — der Container benötigt einen Befehl aus irgendeinem Punkt
Immer gesetzt für Authentifizierungs-Cookies["cmd", "arg"] exec-Formcmd arg
Immer gesetzt für Authentifizierungs-Cookiescmd arg shell-Form/bin/sh -c "cmd arg"
["entry"] exec-FormImmer gesetzt für Authentifizierungs-Cookiesentry
["entry"] exec-Form["arg1", "arg2"] exec-Formentry arg1 arg2
["entry"] exec-Formcmd arg shell-Formentry /bin/sh -c "cmd arg" — fast sicher falsch
entry shell-Form["arg1"] exec-Form/bin/sh -c "entry"CMD wird stumm ignoriert
entry shell-Formcmd arg shell-Form/bin/sh -c "entry"CMD wird stumm ignoriert

Die beiden Zeilen mit „CMD wird stumm ignoriert“ verursachen einen überproportionalen Anteil an Docker-Debug-Sitzungen. Shell-Form ENTRYPOINT verbindet sich nicht mit CMD — es ignoriert es vollständig. Docker warnt Sie nicht davor.

Shell-Form vs Exec-Form: Der Signal-Verarbeitungs-Abgrund

Beide Befehle akzeptieren zwei Formen, und die Wahl ist wichtiger als die meisten Dockerfile-Tutorials annehmen.

Exec-Form (Array-Syntax):

ENTRYPOINT ["nginx", "-g", "daemon off;"]

Ihr Binärprogramm startet direkt. Es wird PID 1. Wenn Docker SIGTERM sendet, um den Container zu stoppen, erhält Ihr Prozess es. Eine graceful Shutdown funktioniert. Logs werden geleert. Verbindungen schließen sich sauber.

Shellform (einfacher String):

ENTRYPOINT nginx -g "daemon off;"

Docker führt dies als /bin/sh -c "nginx -g daemon off;"aus. Die Shell wird PID 1. Wenn SIGTERM kommt, sh erhält es — und sh leitet die Signale nicht an untergeordnete Prozesse weiter. Ihr Container hängt 10 Sekunden lang, erhält SIGKILLund stirbt ohne Reinigung. Jedes Mal.

Verwenden Sie die exec-Form. Immer. Für beide ENTRYPOINT und CMD.

Drei Muster, die tatsächlich funktionieren

Muster 1: Feste Ausführbarkeit, überschreibbare Standardwerte

Das richtige Muster für die meisten Produktionscontainer. Das Binärprogramm ist fest; die Flags können im Laufzeitmodus gewechselt werden:

ENTRYPOINT ["/app/server"]
CMD ["--port", "8080", "--env", "production"]
# Use defaults
docker run myimage

# Override at deploy time
docker run myimage --port 9090 --env staging

Muster 2: Wrapper-Skript mit exec

Wenn Sie Init-Logik vor Ihrem Hauptprozess benötigen (Migrations, Geheimnisse, Signal-Verarbeitung), verwenden Sie ein Wrapper-Skript. Die kritische Zeile ist exec "$@" am Ende — es ersetzt die Shell-Prozess mit Ihrem CMD, sodass Ihr Binärprogramm PID 1 wird:

#!/bin/sh
set -e

echo "Running migrations..."
/app/migrate

# Hand off to CMD — exec replaces shell, so /app/server becomes PID 1
exec "$@"
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/app/server", "--port", "8080"]

Wenn Sie exec "$@"überspringen,

bleibt die Shell als PID 1 und Sie sind zurück bei den Signal-Verarbeitungsproblemen.

Muster 3: Nur CMD, kein ENTRYPOINT

FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

Geeignet für Entwicklungsimages oder Tooling-Container, bei denen Sie beliebige Befehle in derselben Umgebung ausführen möchten: docker run myimage bash Für Produktionsumgebungen ist Muster 1 oder 2 sicherer — Sie möchten nicht, dass ein falsch konfiguriertes Bereitstellungs-Skript versehentlich

und Ihren Server durch eine Shell-Sitzung ersetzt.

Nichts. docker exec führt einen Befehl in einem bereits laufenden Container aus. Es umgeht ENTRYPOINT vollständig. Sie müssen sich nicht mit ENTRYPOINT auffassen, wenn Sie docker exec mycontainer bash ausführen, um herumzuschauen — Sie sprechen mit der laufenden Containerumgebung, nicht mit der Startkonfiguration.

Die Verwirrung kommt meist von Personen, die mit docker exec debuggen und bestätigen, dass alles funktioniert, und dann fragen, warum docker run anders verhält. Es sind völlig separate Code-Pfade.

Vor-Start-Checkliste

  • Beide ENTRYPOINT und CMD verwenden Sie die exec-Form (Array-Syntax, nicht einfache Strings)
  • Wenn Sie ein Wrapper-Skript haben, endet es mit exec "$@"
  • Sie haben getestet docker run myimage und docker run myimage --your-flag um sicherzustellen, dass beide Wege funktionieren
  • docker stop mycontainer beendet sich innerhalb von 2 Sekunden (nicht 10 — wenn es 10 ist, haben Sie ein Signalproblem)

Wenn Sie automatisierte Rückmeldung vor dem Dockerfile an einen Registry-Server bringen möchten, IO Tools’ Dockerfile Linter erfassen Shell-Form-Verwendung, fehlende exec in Entry-Point-Skripten und andere Muster, die zu stummen Fehlern im Betrieb führen.

Möchten Sie werbefrei genießen? Werde noch heute werbefrei

Erweiterungen installieren

IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche

Zu Chrome-Erweiterung Zu Kantenerweiterung Zu Firefox-Erweiterung Zu Opera-Erweiterung

Die Anzeigetafel ist eingetroffen!

Anzeigetafel ist eine unterhaltsame Möglichkeit, Ihre Spiele zu verfolgen. Alle Daten werden in Ihrem Browser gespeichert. Weitere Funktionen folgen in Kürze!

ANZEIGE Entfernen?
ANZEIGE Entfernen?
ANZEIGE Entfernen?

Nachrichtenecke mit technischen Highlights

Beteiligen Sie sich

Helfen Sie uns, weiterhin wertvolle kostenlose Tools bereitzustellen

Kauf mir einen Kaffee
ANZEIGE Entfernen?