janela de encaixe: arquivo executável não encontrado em $ PATH

216

Tenho uma imagem do docker que é instalada grunt, mas quando tento executá-la, recebo um erro:

Error response from daemon: Cannot start container foo_1: \
    exec: "grunt serve": executable file not found in $PATH

Se eu executar o bash no modo interativo, gruntestará disponível.

O que estou fazendo de errado?

Aqui está o meu Dockerfile:

# https://registry.hub.docker.com/u/dockerfile/nodejs/ (builds on ubuntu:14.04)
FROM dockerfile/nodejs

MAINTAINER My Name, [email protected]

ENV HOME /home/web
WORKDIR /home/web/site

RUN useradd web -d /home/web -s /bin/bash -m

RUN npm install -g grunt-cli
RUN npm install -g bower

RUN chown -R web:web /home/web
USER web

RUN git clone https://github.com/repo/site /home/web/site

RUN npm install
RUN bower install --config.interactive=false --allow-root

ENV NODE_ENV development

# Port 9000 for server
# Port 35729 for livereload
EXPOSE 9000 35729
CMD ["grunt"]
Steve Lorimer
fonte
você pode tentar construir a janela de encaixe usando CMD grunt? Ou você pode tentar executar o comando grunt passando o caminho completo?
mgaido
@ mark91, por favor, você poderia elaborar o que está pedindo para re-usar usando? CMD grunt?Quer dizer, solte o ["e "]?
Steve Lorimer
Apenas tentei - e funcionou - obrigado! Assim, para qualquer outra pessoa entrar, a mudança CMD ["grunt"]paraCMD grunt
Steve Lorimer
10
Isso ocorre porque se você CMD ["grunt"]usar outro shell para executar o comando, então nesse shell provavelmente não será definido $ PATH.
mgaido
Veja também stackoverflow.com/q/48001082/798677
The Brazilian Guy

Respostas:

198

Quando você usa o formato exec para um comando (por exemplo CMD ["grunt"], uma matriz JSON com aspas duplas), ele será executado sem um shell. Isso significa que a maioria das variáveis ​​de ambiente não estará presente.

Se você especificar seu comando como uma sequência regular (por exemplo CMD grunt), a sequência posterior CMDserá executada com /bin/sh -c.

Mais informações sobre isso estão disponíveis na seção CMD da referência do Dockerfile .

Kevan Ahlquist
fonte
2
Este é um link para a parte do CMD da referência docs.docker.com/engine/reference/builder/#cmd
Calvin
Desculpe essa pergunta idiota, mas como você pode executar um comando linux sem um shell? Qual seria o equivalente a fazer isso em uma máquina Linux (sem usar o docker)?
wisbucky
1
Para responder minha própria pergunta, é semelhante a fazer sudo setor (exec set). Isso irá falhar porque eles executam os comandos sem um shell (e seté um shell embutido). No entanto, sudo lse (exec ls)funcionará porque lsé um arquivo binário real /bin/ls.
wisbucky 4/09/19
315

Este foi o primeiro resultado no google quando colei minha mensagem de erro e é porque meus argumentos estavam fora de ordem.

O nome do contêiner deve estar após todos os argumentos.

Ruim:

docker run <container_name> -v $(pwd):/src -it

Boa:

docker run -v $(pwd):/src -it <container_name>
sarink
fonte
132
Se você sempre ler a documentação completamente antes de começar a codificar, nunca fará nada. Quando você comprou seu carro novo, leu o manual de 200 páginas antes de levá-lo para casa? Não. E quando houve um problema com seu carro, você pesquisou no Google primeiro ou foi buscar o manual? Isso é totalmente razoável, só posso imaginar todas as pessoas que acharam útil, mas não clicaram no botão de votação! O que é meio irracional é que esta resposta totalmente não relacionada seja o primeiro resultado do Google para essa mensagem de erro ou que o CLI do docker não seja intuitivo e implacável. Felicidades.
sarink
8
Em muitos scripts, a ordem dos sinalizadores não é importante; portanto, posso ver por que isso pode acontecer com alguém. A resposta é bastante útil. Escusado será dizer que a mensagem de erro do docker não é útil.
Marios
9
Uau, eu teria lutado por um tempo se não fosse por essa resposta. Por UNIX não tem um padrão, analisador argumento CLI flexível e poderosa já ...?
lleaff
1
Este foi o problema para mim. Colocar nome do contêiner no final parecia funcionar
Rob Segal
3
Eu fui enganado pela resposta aceita, queria escrever a minha, mas parece que já está aqui. Então eu posso confirmar que Isto resolve o problema ...
Arturas M
24

Eu encontrei o mesmo problema. Eu fiz o seguinte:

docker run -ti devops -v /tmp:/tmp /bin/bash

Quando eu mudo para

docker run -ti -v /tmp:/tmp devops /bin/bash

Funciona bem.

keniee van
fonte
1
Funcionou para mim cara, mas eu não entendo o uso -vdaqui. -vé vincular a montagem de um volume (conforme descrito em docker run --help | grep "\-v"), para mim, eu já /tmpmontei nas File Sharing(configurações do Docker), então por que devo usá-lo novamente?
Ahmad
12

Existem várias razões possíveis para um erro como este.

No meu caso, foi devido ao arquivo executável ( docker-entrypoint.shdo Dockerfile do blog do Ghost ) não ter o modo de arquivo executável após o download.

Solução: chmod +x docker-entrypoint.sh

Ben Creasy
fonte
Este é o comentário que me apontou a resposta certa. Eu tive que copiar o arquivo e depois chmod.
beyondtheteal
7

Um contêiner do Docker pode ser construído sem um shell (por exemplo, https://github.com/fluent/fluent-bit-docker-image/issues/19 ).

Nesse caso, você pode copiar um shell estaticamente compilado e executá-lo, por exemplo

docker create --name temp-busybox busybox:1.31.0
docker cp temp-busybox:/bin/busybox busybox
docker cp busybox mycontainerid:/busybox
docker exec -it mycontainerid /bin/busybox sh
Gajus
fonte
4

Por algum motivo, recebo esse erro, a menos que adicione o clarificador "bash". Mesmo adicionando "#! / Bin / bash" ao topo do meu arquivo de ponto de entrada não ajudou.

ENTRYPOINT [ "bash", "entrypoint.sh" ]
além do ideal
fonte
@SteveLorimer, sim. Eu fiz um COPYe depois RUN chmod +x /compile_nibbler.shantes da chamada do ponto de entrada.
beyondtheteal
1

Eu tive o mesmo problema. Depois de pesquisar bastante, não consegui descobrir como corrigi-lo.

De repente, notei meu erro estúpido :)

Conforme mencionado nos documentos , a última parte docker runé o comando que você deseja executar e seus argumentos após carregar o contêiner.

NÃO O NOME DO RECIPIENTE !!!

Esse foi o meu erro embaraçoso.

Abaixo, forneci uma imagem da minha linha de comando para ver o que fiz de errado.

E essa é a correção conforme mencionado nos documentos .

insira a descrição da imagem aqui

Parsa
fonte
-7

para fazê-lo funcionar, adicione uma referência suave a / usr / bin:

ln -s $ (qual nó) / usr / bin / node

ln -s $ (que npm) / usr / bin / npm

vacavaca
fonte
1
Por favor, adicione uma descrição sobre como isso o ajudará.
Mathews Ensolarado