docker: archivo ejecutable no encontrado en $ PATH

216

Tengo una imagen acoplable que se instala grunt, pero cuando intento ejecutarla, aparece un error:

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

Si ejecuto bash en modo interactivo, gruntestá disponible.

¿Qué estoy haciendo mal?

Aquí está mi 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
fuente
¿Puedes intentar construir la ventana acoplable CMD grunt? ¿O puede intentar ejecutar el comando gruñido pasando la ruta completa?
mgaido
@ mark91 por favor, ¿podría explicar lo que está pidiendo reconstruir usando? CMD grunt?¿Quiere decir soltar el ["y "]?
Steve Lorimer
Solo lo probé, y funcionó, ¡gracias! Entonces, para cualquier persona que venga, cambie CMD ["grunt"]aCMD grunt
Steve Lorimer
10
Esto se debe a que si CMD ["grunt"]utiliza otro shell para ejecutar el comando, es probable que en ese shell $ PATH no se establezca.
mgaido
Ver también stackoverflow.com/q/48001082/798677
Ese tipo brasileño el

Respuestas:

198

Cuando utiliza el formato exec para un comando (por ejemplo CMD ["grunt"], una matriz JSON con comillas dobles), se ejecutará sin un shell. Esto significa que la mayoría de las variables de entorno no estarán presentes.

Si especifica su comando como una cadena normal (por ejemplo CMD grunt), la cadena posterior CMDse ejecutará con /bin/sh -c.

Más información sobre esto está disponible en la sección CMD de la referencia de Dockerfile .

Kevan Ahlquist
fuente
2
Este es un enlace a la parte de CMD de la referencia docs.docker.com/engine/reference/builder/#cmd
Calvin
Disculpe esta pregunta tonta, pero ¿cómo puede ejecutar un comando de Linux sin un shell? ¿Cuál sería el equivalente a hacer esto en una máquina Linux (sin usar docker)?
wisbucky
1
Para responder a mi propia pregunta, es similar a hacer sudo seto (exec set). Esos fallarán porque ejecutan los comandos sin un shell (y setes un shell incorporado). Sin embargo, sudo lsy (exec ls)funcionará porque lses un archivo binario real /bin/ls.
wisbucky
315

Este fue el primer resultado en Google cuando pegué mi mensaje de error, y es porque mis argumentos estaban fuera de orden.

El nombre del contenedor debe ser después de todos los argumentos.

Malo:

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

Bueno:

docker run -v $(pwd):/src -it <container_name>
sarink
fuente
132
Si siempre lees la documentación detenidamente antes de comenzar a codificar, nunca harías nada. Cuando compró su auto nuevo, ¿leyó el manual de 200 páginas antes de conducirlo a casa? No. Y cuando hubo un problema con su automóvil, ¿lo buscó en Google primero o buscó el manual? Esto es totalmente razonable, ¡solo puedo imaginar a todas las personas que lo encontraron útil pero que no han hecho clic en el botón de votar! Lo que no es razonable es que esta respuesta totalmente no relacionada es el primer resultado de Google para este mensaje de error, o que el cli de Docker no es intuitivo e implacable. Salud.
sarink
8
En muchos scripts, el orden de las banderas no es importante, así que puedo ver por qué esto le puede pasar a cualquiera. La respuesta es bastante útil. No hace falta decir que el mensaje de error de Docker no es útil en absoluto.
marios
99
Wow, habría luchado por un tiempo si no fuera por esta respuesta. ¿Por qué UNIX ya no tiene un analizador de argumentos CLI estándar, flexible y potente? ...
lleaff
1
Este fue el problema para mí. Poner el nombre del contenedor al final parecía funcionar
Rob Segal
3
La respuesta aceptada me engañó, quería escribir la mía, pero parece que ya está aquí. Entonces puedo confirmar que esto resuelve el problema ...
Arturas M
24

Encontré el mismo problema. Hice lo siguiente:

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

Cuando lo cambio a

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

funciona bien.

Keniee van
fuente
1
Funcionó para mí, hombre, pero no entiendo el uso de -vaquí. -ves unir el montaje de un volumen (como se describe en docker run --help | grep "\-v"), para mí, ya lo he /tmpmontado en la File Sharing(Configuración de Docker), entonces, ¿por qué debería usarlo nuevamente?
Ahmad
12

Hay varias razones posibles para un error como este.

En mi caso, se debió a que el archivo ejecutable ( docker-entrypoint.shdel Dockerfile de Ghost blog ) no tenía el modo de archivo ejecutable después de haberlo descargado.

Solución: chmod +x docker-entrypoint.sh

Ben Creasy
fuente
Este es el comentario que me señaló la respuesta correcta. Tuve que COPIAR el archivo y luego modificarlo.
beyondtheteal
7

Se puede construir un contenedor Docker sin un shell (por ejemplo, https://github.com/fluent/fluent-bit-docker-image/issues/19 ).

En este caso, puede copiar un shell compilado estáticamente y ejecutarlo, p. Ej.

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
fuente
4

Por alguna razón, obtengo ese error a menos que agregue el clarificador "bash". Incluso agregar "#! / Bin / bash" a la parte superior de mi archivo de punto de entrada no ayudó.

ENTRYPOINT [ "bash", "entrypoint.sh" ]
más allá de lo real
fuente
@SteveLorimer, sí. Hice una COPYy luego RUN chmod +x /compile_nibbler.shantes de la llamada del punto de entrada.
beyondtheteal
1

Tuve el mismo problema, después de mucho googlear, no pude encontrar cómo solucionarlo.

De repente noté mi estúpido error :)

Como se menciona en los documentos , la última parte de docker runes el comando que desea ejecutar y sus argumentos después de cargar el contenedor.

NO ES EL NOMBRE DEL CONTENEDOR !!!

Ese fue mi error vergonzoso.

A continuación, le proporcioné la imagen de mi línea de comando para ver qué he hecho mal.

Y esta es la solución como se menciona en los documentos .

ingrese la descripción de la imagen aquí

Parsa
fuente
-7

para que funcione, agregue una referencia suave a / usr / bin:

ln -s $ (qué nodo) / usr / bin / node

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

vacavaca
fuente
1
Agregue una descripción sobre cómo lo ayudará.
Mathews Sunny