docker: fichier exécutable introuvable dans $ PATH

216

J'ai une image docker qui s'installe grunt, mais quand j'essaye de l'exécuter, j'obtiens une erreur:

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

Si je lance bash en mode interactif, gruntest disponible.

Qu'est-ce que je fais mal?

Voici mon 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
la source
pouvez-vous essayer de construire le docker en utilisant CMD grunt? Ou pouvez-vous essayer d'exécuter la commande grunt en passant le chemin complet?
mgaido
@ mark91, pourriez-vous expliquer ce que vous demandez à reconstruire en utilisant CMD grunt?Voulez-vous dire supprimer le ["et "]?
Steve Lorimer
Je viens de l'essayer - et cela a fonctionné - merci! Donc, pour toute autre personne entrant, changez CMD ["grunt"]pourCMD grunt
Steve Lorimer
10
En effet, si vous CMD ["grunt"]utilisez un autre shell pour exécuter la commande, il est probable que dans ce shell, $ PATH ne soit pas défini.
mgaido
Voir aussi stackoverflow.com/q/48001082/798677
That Brazilian Guy

Réponses:

198

Lorsque vous utilisez le format exec pour une commande (par exemple CMD ["grunt"], un tableau JSON avec des guillemets doubles), elle sera exécutée sans shell. Cela signifie que la plupart des variables d'environnement ne seront pas présentes.

Si vous spécifiez votre commande comme une chaîne régulière (par exemple CMD grunt), la chaîne suivante CMDsera exécutée avec /bin/sh -c.

Plus d'informations à ce sujet sont disponibles dans la section CMD de la référence Dockerfile .

Kevan Ahlquist
la source
2
Ceci est un lien vers la partie CMD de la référence docs.docker.com/engine/reference/builder/#cmd
Calvin
Excusez cette stupide question, mais comment pouvez-vous exécuter une commande linux sans shell? Quel serait l'équivalent de le faire sur une machine Linux (sans utiliser Docker)?
wisbucky
1
Pour répondre à ma propre question, cela revient à faire sudo setou (exec set). Ceux-ci échoueront car ils exécutent les commandes sans shell (et setsont un shell intégré). Cependant, sudo lset (exec ls)fonctionnera car il lss'agit d'un fichier binaire réel /bin/ls.
wisbucky
315

Ce fut le premier résultat sur google lorsque j'ai collé mon message d'erreur, et c'est parce que mes arguments étaient en panne.

Le nom du conteneur doit être après tous les arguments.

Mauvais:

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

Bien:

docker run -v $(pwd):/src -it <container_name>
Sarink
la source
132
Si vous lisez toujours attentivement la documentation avant de commencer à coder, vous ne ferez rien. Lorsque vous avez acheté votre nouvelle voiture, avez-vous lu le manuel de 200 pages avant de la ramener à la maison? Non. Et quand il y avait un problème avec votre voiture, l'avez-vous d'abord recherchée sur Google, ou avez-vous obtenu le manuel? C'est tout à fait raisonnable, je ne peux qu'imaginer toutes les personnes qui l'ont trouvé utile mais n'ont pas cliqué sur le bouton de vote positif! Ce qui est déraisonnable, c'est que cette réponse totalement indépendante est le premier résultat google pour ce message d'erreur, ou que le docker cli est intuitif et impitoyable. À votre santé.
Sarink
8
Dans de nombreux scripts, l'ordre des drapeaux n'est pas important, donc je peux voir pourquoi cela peut arriver à n'importe qui. La réponse est assez utile. Inutile de dire que le message d'erreur de docker n'est pas du tout utile.
marios
9
Wow, j'aurais lutté pendant un certain temps sans cette réponse. Pourquoi UNIX ne dispose-t-il pas déjà d'un analyseur d'arguments CLI standard, flexible et puissant? ...
lleaff
1
C'était le problème pour moi. Mettre le nom du conteneur à la fin semblait fonctionner
Rob Segal
3
J'ai été induit en erreur par la réponse acceptée, je voulais écrire la mienne, mais il semble qu'elle soit déjà là. Je peux donc confirmer que cela résout le problème ...
Arturas M
24

J'ai trouvé le même problème. J'ai fait ce qui suit:

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

Quand je le change en

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

ça fonctionne bien.

keniee van
la source
1
Ça a marché pour moi mec, mais je ne comprends pas l'utilisation d' -vici. -vest de lier monter un volume (comme décrit dans docker run --help | grep "\-v"), pour moi, je l'ai déjà /tmpmonté dans les File Sharing(paramètres Docker), alors pourquoi devrais-je l'utiliser à nouveau?
Ahmad
12

Il existe plusieurs raisons possibles à une erreur de ce type.

Dans mon cas, cela était dû au fait que le fichier exécutable ( docker-entrypoint.shdu blog Ghost Dockerfile ) n'avait pas le mode de fichier exécutable après l'avoir téléchargé.

Solution: chmod +x docker-entrypoint.sh

Ben Creasy
la source
C'est le commentaire qui m'a indiqué la bonne réponse. J'ai dû COPIER le fichier puis le modifier.
Beyondtheteal
7

Un conteneur Docker peut être construit sans shell (par exemple https://github.com/fluent/fluent-bit-docker-image/issues/19 ).

Dans ce cas, vous pouvez copier un shell compilé statiquement et l'exécuter, par exemple

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
la source
4

Pour une raison quelconque, j'obtiens cette erreur à moins que j'ajoute le clarificateur "bash". Même l'ajout de "#! / Bin / bash" en haut de mon fichier de point d'entrée n'a pas aidé.

ENTRYPOINT [ "bash", "entrypoint.sh" ]
au-delà de la réalité
la source
@SteveLorimer, oui. J'ai fait un COPY, puis RUN chmod +x /compile_nibbler.shavant l'appel du point d'entrée.
Beyondtheteal
1

J'ai eu le même problème, après beaucoup de recherches sur Google, je n'ai pas pu trouver de solution.

Soudain, j'ai remarqué ma stupide erreur :)

Comme mentionné dans les documents , la dernière partie dedocker run la commande que vous souhaitez exécuter et ses arguments après le chargement du conteneur.

PAS LE NOM DU RÉCIPIENT !!!

C'était mon embarrassante erreur.

Ci-dessous, je vous ai fourni l'image de ma ligne de commande pour voir ce que j'ai fait de mal.

Et c'est le correctif tel que mentionné dans les documents .

entrez la description de l'image ici

Parsa
la source
-7

pour le faire fonctionner, ajoutez une référence douce à / usr / bin:

ln -s $ (quel nœud) / usr / bin / node

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

vacavaca
la source
1
Veuillez ajouter une description de la façon dont cela l'aidera.
Mathews Sunny