Docker ENTRYPOINT im Vergleich zu CMD — Dein Container hat dich belogen
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.
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:
| ENTRYPOINT | CMD | Was tatsächlich ausgeführt wird |
|---|---|---|
| Immer gesetzt für Authentifizierungs-Cookies | Immer gesetzt für Authentifizierungs-Cookies | Fehler — der Container benötigt einen Befehl aus irgendeinem Punkt |
| Immer gesetzt für Authentifizierungs-Cookies | ["cmd", "arg"] exec-Form | cmd arg |
| Immer gesetzt für Authentifizierungs-Cookies | cmd arg shell-Form | /bin/sh -c "cmd arg" |
["entry"] exec-Form | Immer gesetzt für Authentifizierungs-Cookies | entry |
["entry"] exec-Form | ["arg1", "arg2"] exec-Form | entry arg1 arg2 ✓ |
["entry"] exec-Form | cmd arg shell-Form | entry /bin/sh -c "cmd arg" — fast sicher falsch |
entry shell-Form | ["arg1"] exec-Form | /bin/sh -c "entry" — CMD wird stumm ignoriert |
entry shell-Form | cmd 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
ENTRYPOINTundCMDverwenden Sie die exec-Form (Array-Syntax, nicht einfache Strings) - Wenn Sie ein Wrapper-Skript haben, endet es mit
exec "$@" - Sie haben getestet
docker run myimageunddocker run myimage --your-flagum sicherzustellen, dass beide Wege funktionieren docker stop mycontainerbeendet 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.
Erweiterungen installieren
IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche
恵 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!
Unverzichtbare Tools
Alle Neuheiten
AlleAktualisieren: Unser neuestes Werkzeug was added on Juni 25, 2026
