La sintaxis JSON de CMD
(y RUN
y ENTRYPOINT
) pasan los argumentos al kernel directamente como un syscall 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 comandos múltiples, etc., en la llamada al sistema ejecutivo. El syscall solo toma el ejecutable para ejecutarse y la lista de argumentos para pasar a ese ejecutable, y lo ejecuta.
Los caracteres como $
expandir variables, ;
separar comandos,
(espacio) para separar argumentos &&
y ||
encadenar comandos, >
para redireccionar resultados, |
canalizar entre comandos, etc., son todas características del shell y necesitan algo como /bin/sh
o /bin/bash
para 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 múltiples 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 dará como resultado un retraso de 10 segundos y la destrucción de su contenedor por parte del acoplador. El manejo de la señal se puede mitigar utilizando el exec
comando de shell :
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
Sin embargo, el manejo de procesos que fallan silenciosamente en segundo plano requiere que cambie a algún tipo de administrador multiproceso como supervisor, o preferiblemente divida su aplicación en múltiples contenedores y los implemente con algo como docker-compose.
exec
formulario, ya que es el preferido? ¿Por qué se prefiere? ¿O debería usar unashell
forma más simple ?