La syntaxe json de CMD
(et RUN
et ENTRYPOINT
) passez les arguments au noyau directement en tant qu'appel système exec. Il n'y a pas de séparation de la commande des arguments par des espaces, d'échappement des guillemets, de redirection d'E / S, de substitution de variable, de tuyauterie entre les commandes, d'exécution de plusieurs commandes, etc., dans l'appel système 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.
Des personnages comme $
pour développer des variables, ;
pour séparer les commandes,
(espace) pour séparer les arguments, &&
et ||
pour enchaîner les commandes, >
pour la redirection de sortie, |
pour diriger entre les commandes, etc., sont toutes les fonctionnalités du shell et ont besoin de quelque chose comme /bin/sh
ou /bin/bash
les interpréter et les mettre en œuvre.
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 façon à l'intérieur d'un conteneur car il n'y a pas de gestion des erreurs si votre première commande échoue, surtout si elle s'exécute en arrière-plan. Vous laissez également un shell en cours d'exécution en tant que pid 1 à l'intérieur du conteneur, ce qui interrompra la gestion du signal, entraînant un délai de 10 secondes et une destruction ingrate de votre conteneur par docker. La gestion du signal peut être atténuée en utilisant le shell exec
commande:
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
Cependant, la gestion des processus qui échouent silencieusement en arrière-plan nécessite de passer à une sorte de gestionnaire multi-processus comme supervisord, ou de préférence de diviser votre application en plusieurs conteneurs et de les déployer avec quelque chose comme docker-compose.