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.