Die json-Syntax von CMD
(und RUN
und ENTRYPOINT
) übergibt die Argumente direkt als exec-Syscall an den Kernel. Es gibt keine Trennung des Befehls von den Argumenten durch Leerzeichen, Anführungszeichen, E / A-Umleitung, Variablensubstitution, Weiterleiten zwischen Befehlen, Ausführen mehrerer Befehle usw. im exec-Systemaufruf. Der syscall führt nur die ausführbare Datei aus und listet die Argumente auf, die an diese ausführbare Datei übergeben werden sollen, und führt sie aus.
Zeichen wie $
das Erweitern von Variablen, ;
das Trennen von Befehlen
(Leerzeichen), das Trennen von Argumenten &&
und ||
das Verketten von Befehlen, das >
Umleiten von Ausgaben, das Weiterleiten |
zwischen Befehlen usw. sind alle Merkmale der Shell und benötigen etwas Ähnliches /bin/sh
oder /bin/bash
zum Interpretieren und Implementieren.
Wenn Sie zur Zeichenfolgensyntax von wechseln CMD
, führt docker Ihren Befehl mit einer Shell aus:
CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm
Ansonsten macht Ihre zweite Syntax genau dasselbe:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Beachten Sie, dass ich nicht empfehle, mehrere Befehle auf diese Weise innerhalb eines Containers auszuführen, da es keine Fehlerbehandlung gibt, wenn Ihr erster Befehl fehlschlägt, insbesondere wenn er im Hintergrund ausgeführt wird. Sie lassen auch eine Shell als PID 1 im Container laufen, die die Signalverarbeitung unterbricht, was zu einer Verzögerung von 10 Sekunden und einem unbefriedigenden Töten Ihres Containers durch den Docker führt. Die Signalbehandlung kann mithilfe des Shell- exec
Befehls verringert werden :
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
Wenn Sie jedoch Prozesse verarbeiten möchten, die im Hintergrund unbemerkt fehlschlagen, müssen Sie zu einer Art Multi-Prozess-Manager wie Supervisord wechseln oder Ihre Anwendung vorzugsweise in mehrere Container aufteilen und mit Docker-Compose bereitstellen.
exec
Formular weiterhin verwenden , da es das bevorzugte Formular ist? Warum ist es bevorzugt? Oder soll ich einfachereshell
Form verwenden?