CMD vs ENTRYPOINT - den Unterschied im Dockerfile verstehen
CMD vs ENTRYPOINT - den Unterschied im Dockerfile verstehen
CMD und ENTRYPOINT sehen auf den ersten Blick ähnlich aus — beide legen fest, was beim Container-Start ausgeführt wird. Der Unterschied liegt darin, was sich zur Laufzeit noch überschreiben lässt.
ENTRYPOINT: das Executable
ENTRYPOINT definiert den Hauptprozess des Containers — das Programm, das immer gestartet wird. Es lässt sich bei docker run nicht einfach überschreiben.
ENTRYPOINT ["python", "app.py"]
docker run myimage # führt: python app.py aus
docker run myimage --debug # führt: python app.py --debug aus
Argumente hinter dem Image-Namen werden an den Entrypoint angehängt, nicht ersetzt.
CMD: die Standard-Argumente
CMD definiert Standard-Argumente, die beim Start übergeben werden — aber nur wenn man nichts anderes angibt. Gibt man bei docker run nach dem Image-Namen etwas an, überschreibt das CMD vollständig.
CMD ["python", "app.py"]
docker run myimage # führt: python app.py aus
docker run myimage python other.py # führt: python other.py aus (CMD überschrieben)
Kombination: ENTRYPOINT + CMD
Die häufigste und sinnvollste Kombination: ENTRYPOINT legt das Executable fest, CMD liefert die überschreibbaren Standardargumente.
ENTRYPOINT ["python"]
CMD ["app.py"]
docker run myimage # führt: python app.py aus
docker run myimage other.py # führt: python other.py aus
Diese Kombination macht Container zu "Kommandozeilen-Werkzeugen" mit sinnvollen Defaults.
Exec Form vs. Shell Form
Beide Instructions gibt es in zwei Schreibweisen:
Exec Form (empfohlen): Prozess läuft direkt als PID 1, empfängt Signale korrekt.
ENTRYPOINT ["nginx", "-g", "daemon off;"]
CMD ["app.py"]
Shell Form: Prozess läuft als Kind von /bin/sh -c, PID 1 ist die Shell. Signale wie SIGTERM erreichen den eigentlichen Prozess oft nicht.
ENTRYPOINT nginx -g "daemon off;"
CMD python app.py
Für Produktions-Container immer die Exec Form verwenden.
ENTRYPOINT zur Laufzeit überschreiben
Wenn es wirklich nötig ist, lässt sich auch der Entrypoint überschreiben — aber nur mit dem expliziten --entrypoint-Flag:
docker run --entrypoint /bin/sh myimage
Häufiger Fehler
Wer CMD für den Hauptprozess verwendet und erwartet, dass er immer läuft, wird überrascht sein, wenn ein simples docker run myimage bash den Prozess ersetzt. Für unüberschreibbare Hauptprozesse: ENTRYPOINT verwenden.