No entiendo lo que sucede cuando intento ejecutar dos comandos en tiempo de ejecución a través de la directiva CMD en `Dockerfile. Supuse que esto debería funcionar:
CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]
Pero no está funcionando. El contenedor no ha comenzado. Así que tuve que hacerlo así:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
No entiendo. ¿Porqué es eso? ¿Por qué la primera línea no es la correcta? ¿Alguien puede explicarme estas cosas de "formato de shell CMD vs formato JSON, etc."? En palabras simples
Solo para tener en cuenta: lo mismo command:
sucedió con la directiva docker-compose.yml
, como se esperaba.
exec
formulario, ya que es el preferido? ¿Por qué se prefiere? ¿O debería usar unashell
forma más simple ?CMD [ "sh", "-c", "echo", "$HOME"]
. ¿Por qué noCMD ["sh", "-c", "echo $HOME"]
o, para el casoCMD ["sh -c echo $HOME"]
,?No te lo pongas difícil. Simplemente cree un archivo bash "start.sh":
en su Dockerfile hacer:
fuente
La sintaxis JSON de
CMD
(yRUN
yENTRYPOINT
) 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:De lo contrario, su segunda sintaxis hace exactamente lo mismo:
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 :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.
fuente
Supongo que el primer comando falla porque en la forma DOCKER CMD, solo se ejecuta el primer parámetro, el resto se alimenta a este comando.
La segunda forma funciona porque todos los comandos están separados por ";" son alimentados al comando sh, que los ejecuta.
fuente
No creo que debas poner una coma después del "inicio"
En lugar de usar
tratar
como Docker usa "sh -c", el comando anterior se ejecutará de la siguiente manera
fuente
sh -c
en ese escenario.