A sintaxe json de CMD
(e RUN
e ENTRYPOINT
) passa os argumentos para o kernel diretamente como um syscall exec. Não há separação do comando dos argumentos por espaços, escape de aspas, redirecionamento de E / S, substituição de variável, canalização entre comandos, execução de vários comandos etc. no syscall exec. O syscall leva apenas o executável para executar e a lista de argumentos a serem transmitidos para esse executável e o executa.
Caracteres gostam $
de expandir variáveis, ;
separar comandos,
(espaço) para separar argumentos &&
e ||
encadear comandos, >
para redirecionamento de saída, |
canalizar entre comandos, etc., são todos recursos do shell e precisam de algo como /bin/sh
ou /bin/bash
para interpretá-los e implementá-los.
Se você alternar para a sintaxe da cadeia de caracteres CMD
, o docker executará seu comando com um shell:
CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm
Caso contrário, sua segunda sintaxe faz exatamente a mesma coisa:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Observe que eu não recomendo executar vários comandos dessa maneira dentro de um contêiner, pois não há tratamento de erros se o seu primeiro comando falhar, especialmente se for executado em segundo plano. Você também deixa um shell executando o pid 1 dentro do contêiner, o que interrompe o manuseio do sinal, resultando em um atraso de 10 segundos e na morte desagradável do contêiner pelo docker. A manipulação do sinal pode ser atenuada usando o exec
comando shell :
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
No entanto, lidar com processos que falham silenciosamente em segundo plano exige que você alterne para algum tipo de gerenciador de processos múltiplos, como supervisord, ou, de preferência, quebre seu aplicativo em vários contêineres e implante-os com algo como docker-compose.
exec
formulário, pois é o preferido? Por que é preferido? Ou devo usar umashell
forma mais simples ?