La sintaxis json de CMD
(y RUN
y ENTRYPOINT
) pasa los argumentos al núcleo directamente como una llamada de sistema exec. No hay separación del comando de los argumentos por espacios, escape de comillas, redirección de E / s, sustitución de variables, canalización entre comandos, ejecución de múltiples comandos, etc. en la llamada de sistema exec. La syscall sólo toma el ejecutable que se ejecuta y la lista de argumentos para pasar a ese ejecutable, y corre.
Personajes como $
para expandir variables, ;
para separar comandos,
(espacio) para separar argumentos, &&
y ||
para encadenar comandos, >
para redirección de salida, |
canalizar entre comandos, etc., son todas características del shell y necesitan algo como /bin/sh
o /bin/bash
para interpretarlos e implementarlos.
Si cambia a la sintaxis de cadena de CMD
, docker ejecutará su comando con un shell:
CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm
De lo contrario, la segunda sintaxis hace exactamente lo mismo:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Tenga en cuenta que no recomiendo ejecutar varios comandos de esta manera dentro de un contenedor, ya que no hay manejo de errores si el primer comando falla, especialmente si se ejecuta en segundo plano. También deja un shell funcionando como pid 1 dentro del contenedor que interrumpirá el manejo de la señal, lo que resultará en un retraso de 10 segundos y una muerte ingrata de su contenedor por parte de docker. El manejo de la señal se puede mitigar utilizando el shell exec
comando:
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
Sin embargo, el manejo de procesos que fallan silenciosamente en segundo plano requiere cambiar a algún tipo de administrador de múltiples procesos como supervisord, o preferiblemente dividir la aplicación en varios contenedores e implementarlos con algo como docker-compose.