Não entendo o que está acontecendo quando tento executar dois comandos em tempo de execução via diretiva CMD no `Dockerfile. Eu assumi que isso deveria funcionar:
CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]
Mas não está funcionando. O contêiner não foi iniciado. Então eu tive que fazer assim:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Eu não entendo Por que é que? Por que a primeira linha não é o caminho certo? Alguém pode me explicar essas coisas "formato de shell CMD vs formato JSON, etc". Em palavras simples.
Só para nota - a mesma estava com command:
directiva em docker-compose.yml
, como esperado.
exec
formulário, pois é o preferido? Por que é preferido? Ou devo usar umashell
forma mais simples ?CMD [ "sh", "-c", "echo", "$HOME"]
. Por que nãoCMD ["sh", "-c", "echo $HOME"]
ou, nesse casoCMD ["sh -c echo $HOME"]
?Não torne difícil para si mesmo. Basta criar um arquivo bash "start.sh":
no seu Dockerfile, faça:
fonte
A sintaxe json de
CMD
(eRUN
eENTRYPOINT
) 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:Caso contrário, sua segunda sintaxe faz exatamente a mesma coisa:
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 :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.
fonte
Eu acho que o primeiro comando falha porque, no formato DOCKER CMD, apenas o primeiro parâmetro é executado, o restante é alimentado nesse comando.
O segundo formulário funciona porque todos os comandos separados por ";" são alimentados no comando sh, que os executa.
fonte
Eu não acho que você deve colocar semi-vírgula depois de "start"
ao invés de usar
experimentar
como o docker usa "sh -c", o comando acima será executado como abaixo
fonte
sh -c
nesse cenário.