La sintassi json di CMD
(e RUN
e ENTRYPOINT
) passa gli argomenti al kernel direttamente come syscall exec. Non vi è alcuna separazione del comando dagli argomenti da spazi, escape di virgolette, reindirizzamento IO, sostituzione variabile, piping tra comandi, esecuzione di più comandi, ecc., Nel programma di esecuzione exec. Il syscall richiede solo l'esecuzione del file eseguibile e l'elenco degli argomenti da passare al file eseguibile e lo esegue.
I personaggi come $
espandere le variabili, ;
separare i comandi,
(spaziare) per separare gli argomenti &&
e ||
mettere in ordine i comandi, >
per il reindirizzamento dell'output, |
per passare da un comando all'altro, ecc., Sono tutte caratteristiche della shell e hanno bisogno di qualcosa di simile /bin/sh
o /bin/bash
di interpretarle e implementarle.
Se si passa alla sintassi della stringa di CMD
, la finestra mobile eseguirà il comando con una shell:
CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm
Altrimenti, la tua seconda sintassi fa esattamente la stessa cosa:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Nota che non consiglio di eseguire più comandi in questo modo all'interno di un contenitore poiché non vi è alcun errore nella gestione se il tuo primo comando fallisce, specialmente se viene eseguito in background. Lasci anche una shell in esecuzione come pid 1 all'interno del container che interromperà la gestione del segnale, causando un ritardo di 10 secondi e un'uccisione ingrata del container da parte della docker. La gestione del segnale può essere mitigata usando il exec
comando shell :
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
Tuttavia, la gestione silenziosa dei processi in background richiede il passaggio a una sorta di gestore multi-processo come supervisord, o preferibilmente suddividere l'applicazione in più contenitori e distribuirli con qualcosa come docker-compose.
exec
modulo, in quanto è il modulo preferito? Perché è preferito? O dovrei usare unshell
modulo più semplice ?