Die JSON-Syntax von CMD
(und RUN
und ENTRYPOINT
) übergeben Sie die Argumente direkt als exec-Systemaufruf an den Kernel. Es gibt keine Trennung des Befehls von den Argumenten durch Leerzeichen, Escapen von Anführungszeichen, E / A-Umleitung, Variablenersetzung, Weiterleitung zwischen Befehlen, Ausführen mehrerer Befehle usw. im exec-Systemaufruf. Der Systemaufruf benötigt nur die ausführbare Datei und die Liste der Argumente, die an diese ausführbare Datei übergeben werden sollen, und führt sie aus.
Charaktere wie $
so erweitern Sie Variablen, ;
um Befehle zu trennen,
(Leerzeichen) zum Trennen von Argumenten, &&
und ||
um Befehle zu verketten, >
für die Ausgabeumleitung, |
pipe zwischen Befehlen usw. sind alle Funktionen der Shell und benötigen so etwas wie /bin/sh
oder /bin/bash
sie zu interpretieren und umzusetzen.
Wenn Sie zur String-Syntax von wechseln CMD
, docker wird Ihren Befehl mit einer Shell ausführen:
CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm
Andernfalls 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 in einem Container 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, wodurch die Signalverarbeitung unterbrochen wird, was zu einer Verzögerung von 10 Sekunden und einem ungnädigen Beenden Ihres Containers durch Docker führt. Die Signalbehandlung kann durch Verwendung der Shell gemildert werden exec
Befehl:
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
Um jedoch Prozesse zu behandeln, die im Hintergrund stillschweigend fehlschlagen, müssen Sie zu einer Art Multi-Prozess-Manager wie Supervisord wechseln oder Ihre Anwendung vorzugsweise in mehrere Container aufteilen und diese mit so etwas wie docker-compose bereitstellen.