Ich verstehe nicht, was passiert, wenn ich versuche, zwei Befehle zur Laufzeit über die CMD-Direktive in `Dockerfile auszuführen. Ich ging davon aus, dass dies funktionieren sollte:
CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]
Aber es funktioniert nicht. Container hat nicht begonnen. Also musste ich es so machen:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Ich verstehe nicht Warum ist das so? Warum ist die erste Zeile nicht der richtige Weg? Kann mir jemand diese "CMD-Shell-Format vs JSON-Format, etc" Sachen erklären. In einfachen Worten.
Nur zur Kenntnis zu nehmen - dasselbe galt erwartungsgemäß auch für die command:
Direktive docker-compose.yml
.
exec
Formular weiterhin verwenden , da es das bevorzugte Formular ist? Warum ist es bevorzugt? Oder soll ich einfachereshell
Form verwenden?CMD [ "sh", "-c", "echo", "$HOME"]
. Warum nichtCMD ["sh", "-c", "echo $HOME"]
oderCMD ["sh -c echo $HOME"]
?Mach es dir nicht schwer. Erstellen Sie einfach eine Bash-Datei "start.sh":
in deinem Dockerfile mache:
quelle
Die json-Syntax von
CMD
(undRUN
undENTRYPOINT
) ü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:Ansonsten macht Ihre zweite Syntax genau dasselbe:
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 :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.
quelle
Ich vermute, der erste Befehl schlägt fehl, weil in der DOCKER CMD-Form nur der erste Parameter ausgeführt wird, der Rest wird in diesen Befehl eingespeist.
Die zweite Form funktioniert, weil alle Befehle mit ";" werden in den Befehl sh eingespeist, der sie ausführt.
quelle
Ich denke nicht, dass Sie nach "Start" ein Semikomma setzen sollten
anstatt zu verwenden
Versuchen
Da Docker "sh -c" verwendet, wird der obige Befehl wie folgt ausgeführt
quelle
sh -c
in diesem Szenario keine .