La syntaxe json de CMD
(et RUN
et ENTRYPOINT
) transmet les arguments au noyau directement en tant qu'exec syscall. Il n'y a pas de séparation de la commande des arguments par des espaces, d'échappements de guillemets, de redirection IO, de substitution de variable, de canalisation entre les commandes, d'exécution de plusieurs commandes, etc., dans le syscall de exec. L'appel système ne prend que l'exécutable à exécuter et la liste des arguments à transmettre à cet exécutable, et il l'exécute.
Les caractères tels que $
développer les variables, ;
séparer les commandes,
(espace) séparer les arguments &&
et ||
chaîner les commandes, >
rediriger la sortie, |
diriger entre les commandes, etc., sont autant de fonctionnalités du shell et nécessitent quelque chose comme /bin/sh
ou /bin/bash
pour les interpréter et les implémenter.
Si vous passez à la syntaxe de chaîne de CMD
, docker exécutera votre commande avec un shell:
CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm
Sinon, votre deuxième syntaxe fait exactement la même chose:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Notez que je ne recommande pas d'exécuter plusieurs commandes de cette manière à l'intérieur d'un conteneur, car il n'y a pas de traitement d'erreur si votre première commande échoue, surtout si elle s'exécute en arrière-plan. Vous laissez également un shell s'exécutant en tant que pid 1 à l'intérieur du conteneur, ce qui interrompra la gestion des signaux, ce qui entraînera un délai de 10 secondes et une destruction inutile de votre conteneur par le menu fixe. Le traitement du signal peut être atténué en utilisant la exec
commande shell :
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
Cependant, la gestion silencieuse des processus en arrière-plan nécessite que vous passiez à une sorte de gestionnaire multi-processus tel que supervisord ou, de préférence, divisez votre application en plusieurs conteneurs et les déployez avec un logiciel comme docker-compose.
exec
formulaire, car c'est le formulaire préféré? Pourquoi c'est préféré? Ou devrais-je utiliser unshell
formulaire plus simple ?