Nie rozumiem, co się dzieje, gdy próbuję wykonać dwa polecenia w czasie wykonywania przez dyrektywę CMD w `Dockerfile. Zakładałem, że to powinno działać:
CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]
Ale to nie działa. Kontener nie został uruchomiony. Więc musiałem to zrobić w ten sposób:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Nie rozumiem. Dlaczego? Dlaczego pierwsza linia nie jest właściwa? Czy ktoś może mi wyjaśnić te „format powłoki CMD vs. format JSON itp.”. W prostych słowach.
Uwaga: to samo command:
dotyczyło dyrektywy docker-compose.yml
zgodnie z oczekiwaniami.
exec
formularza, ponieważ jest to preferowany? Dlaczego jest to preferowane? Czy powinienem użyć prostszegoshell
formularza?CMD [ "sh", "-c", "echo", "$HOME"]
. Dlaczego nieCMD ["sh", "-c", "echo $HOME"]
lub, jeśli o to chodziCMD ["sh -c echo $HOME"]
,?Nie utrudniaj sobie. Wystarczy utworzyć plik bash „start.sh”:
w swoim pliku Docker wykonaj:
źródło
Składnia JSON
CMD
(aRUN
iENTRYPOINT
) przekazywać argumenty do jądra bezpośrednio jako exec syscall. Nie ma oddzielania polecenia od argumentów spacjami, unikania cudzysłowów, przekierowywania IO, podstawiania zmiennych, łączenia między poleceniami, uruchamiania wielu poleceń itp. W syscall exec. Syscall pobiera tylko plik wykonywalny do uruchomienia i listę argumentów przekazywanych do tego pliku wykonywalnego i uruchamia go.Znaki takie jak
$
rozszerzanie zmiennych,;
oddzielanie poleceń,(spacja) oddzielanie argumentów
&&
i||
łączenie poleceń,>
przekierowywanie danych wyjściowych|
, przechodzenie między poleceniami itp., Są cechami powłoki i wymagają czegoś podobnego/bin/sh
lub/bin/bash
ich interpretacji i implementacji.Jeśli przełączysz się na składnię ciągu
CMD
, doker wykona polecenie z powłoką:W przeciwnym razie druga składnia robi dokładnie to samo:
Zauważ, że nie polecam wykonywania wielu poleceń w ten sposób w kontenerze, ponieważ nie ma obsługi błędów, jeśli pierwsze polecenie nie powiedzie się, szczególnie jeśli działa w tle. Zostawiasz również powłokę działającą jako pid 1 wewnątrz kontenera, co przerwie obsługę sygnału, co spowoduje 10-sekundowe opóźnienie i niesforne zabicie twojego kontenera przez dokera. Obsługę sygnałów można złagodzić za pomocą
exec
polecenia powłoki :Jednak obsługa procesów, które cicho zawodzą w tle, wymaga przejścia do jakiegoś menedżera wieloprocesowego, takiego jak nadzór, lub najlepiej rozbicia aplikacji na wiele kontenerów i wdrożenia ich z czymś w rodzaju dokowania-komponowania.
źródło
Wydaje mi się, że pierwsze polecenie kończy się niepowodzeniem, ponieważ w formie DOCKER CMD wykonywany jest tylko pierwszy parametr, reszta jest wprowadzana do tego polecenia.
Drugi formularz działa, ponieważ wszystkie polecenia są rozdzielone znakiem „;” są wprowadzane do polecenia sh, które je wykonuje.
źródło
Nie sądzę, że powinieneś wstawić przecinek po „starcie”
zamiast używać
próbować
ponieważ okno dokowane używa „sh -c”, powyższe polecenie zostanie wykonane jak poniżej
źródło
sh -c
w tym scenariuszu.