La sintaxis json de CMD
(y RUN
y ENTRYPOINT
) pase 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 al sistema exec. La llamada al sistema solo toma el ejecutable para ejecutar y la lista de argumentos para pasar a ese ejecutable, y lo ejecuta.
Personajes como $
para expandir variables, ;
para separar comandos,
(espacio) para separar argumentos, &&
y ||
para encadenar comandos, >
para la redirección de salida, |
canalizar entre comandos, etc., son todas características del shell y necesitan algo como /bin/sh
o /bin/bash
interpretarlas e implementarlas.
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, su 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 su primer comando falla, especialmente si se ejecuta en segundo plano. También deja un shell ejecutándose como pid 1 dentro del contenedor, lo que interrumpirá el manejo de la señal, lo que provocará un retraso de 10 segundos y la muerte no grata 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, manejar procesos que fallan silenciosamente en segundo plano requiere que cambie a algún tipo de administrador de multiprocesos como supervisord, o preferiblemente divida su aplicación en múltiples contenedores y los implemente con algo como docker-compose.