Docker: Ausführbare Datei nicht in $ PATH gefunden

216

Ich habe ein Docker-Image, das installiert wird grunt, aber wenn ich versuche, es auszuführen, wird eine Fehlermeldung angezeigt:

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

Wenn ich bash im interaktiven Modus ausführe, gruntist verfügbar.

Was mache ich falsch?

Hier ist meine Docker-Datei:

# 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
quelle
Können Sie versuchen, den Docker mit zu erstellen CMD grunt? Oder können Sie versuchen, den Befehl grunt auszuführen, indem Sie den vollständigen Pfad übergeben?
mgaido
@ mark91 Könnten Sie bitte näher erläutern, was Sie für den Wiederaufbau benötigen ? Meinen CMD grunt?Sie damit, das ["und fallen zu lassen "]?
Steve Lorimer
Ich habe es einfach versucht - und es hat funktioniert - danke! Also für alle anderen, die hereinkommen, wechseln Sie CMD ["grunt"]zuCMD grunt
Steve Lorimer
10
Dies liegt daran, dass wenn Sie CMD ["grunt"]eine andere Shell verwenden, um den Befehl auszuführen, in dieser Shell wahrscheinlich $ PATH nicht festgelegt wird.
mgaido
Siehe auch stackoverflow.com/q/48001082/798677
Dieser Brasilianer

Antworten:

198

Wenn Sie das exec-Format für einen Befehl verwenden (z. B. CMD ["grunt"]ein JSON-Array mit doppelten Anführungszeichen), wird es ohne Shell ausgeführt. Dies bedeutet, dass die meisten Umgebungsvariablen nicht vorhanden sind.

Wenn Sie Ihren Befehl als reguläre Zeichenfolge angeben (z. B. CMD grunt), wird die nachfolgende Zeichenfolge CMDmit ausgeführt /bin/sh -c.

Weitere Informationen hierzu finden Sie im CMD-Abschnitt der Dockerfile-Referenz .

Kevan Ahlquist
quelle
2
Dies ist ein Link zum CMD-Teil der Referenz docs.docker.com/engine/reference/builder/#cmd
Calvin
Entschuldigen Sie diese dumme Frage, aber wie können Sie einen Linux-Befehl ohne Shell ausführen? Was wäre das Äquivalent dazu auf einem Linux-Computer (ohne Docker)?
wisbucky
1
Um meine eigene Frage zu beantworten, ist es ähnlich wie sudo setoder (exec set). Diese setschlagen fehl, weil sie die Befehle ohne Shell ausführen (und eine integrierte Shell ist). Allerdings sudo lsund (exec ls)wird funktionieren, da lses sich um eine tatsächliche Binärdatei handelt /bin/ls.
wisbucky
315

Dies war das erste Ergebnis bei Google, als ich meine Fehlermeldung einfügte, und das liegt daran, dass meine Argumente nicht in Ordnung waren.

Der Containername muss nach allen Argumenten stehen.

Schlecht:

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

Gut:

docker run -v $(pwd):/src -it <container_name>
Sarink
quelle
132
Wenn Sie die Dokumentation immer gründlich lesen, bevor Sie mit dem Codieren beginnen, werden Sie nie etwas erledigen. Haben Sie beim Kauf Ihres neuen Autos das 200-seitige Handbuch gelesen, bevor Sie es nach Hause fuhren? Nein. Und als es ein Problem mit Ihrem Auto gab, haben Sie es zuerst googelt oder haben Sie das Handbuch erhalten? Das ist völlig vernünftig, ich kann mir nur alle Leute vorstellen, die es nützlich fanden, aber nicht auf den Upvote-Button geklickt haben! Was unvernünftig ist, ist, dass diese völlig unabhängige Antwort das erste Google-Ergebnis für diese Fehlermeldung ist oder dass die Docker-CLI nicht intuitiv und unversöhnlich ist. Prost.
Sarink
8
In vielen Skripten ist die Reihenfolge der Flags nicht wichtig, daher kann ich sehen, warum dies jedem passieren kann. Die Antwort ist sehr hilfreich. Unnötig zu erwähnen, dass die Fehlermeldung von Docker überhaupt nicht nützlich ist.
Marios
9
Wow, ich hätte eine Weile gekämpft, wenn diese Antwort nicht gewesen wäre. Warum hat UNIX nicht bereits einen standardmäßigen, flexiblen und leistungsstarken CLI-Argument-Parser? ...
Lleaff
1
Das war das Problem für mich. Das Setzen des Containernamens am Ende schien zu funktionieren
Rob Segal
3
Ich wurde durch die akzeptierte Antwort irregeführt, wollte meine eigene schreiben, aber es scheint, dass sie bereits hier ist. So kann ich bestätigen, dass dies das Problem löst ...
Arturas M
24

Ich habe das gleiche Problem gefunden. Ich habe folgendes gemacht:

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

Wenn ich es ändere

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

es funktioniert gut.

Keniee van
quelle
1
Es hat bei mir funktioniert, Mann, aber ich verstehe die Verwendung -vhier nicht. -vUm ein Volume zu binden (wie in beschrieben docker run --help | grep "\-v"), habe ich es bereits /tmpin den File Sharing(Docker-Einstellungen) gemountet. Warum sollte ich es also erneut verwenden?
Ahmad
12

Es gibt mehrere mögliche Gründe für einen solchen Fehler.

In meinem Fall lag es daran, dass der ausführbaren Datei ( docker-entrypoint.shaus dem Ghost-Blog Dockerfile ) der ausführbare Dateimodus fehlte, nachdem ich sie heruntergeladen hatte.

Lösung: chmod +x docker-entrypoint.sh

Ben Creasy
quelle
Dies ist der Kommentar, der mich auf die richtige Antwort hingewiesen hat. Ich musste die Datei kopieren und dann chmod.
Beyondtheteal
7

Ein Docker-Container kann ohne Shell erstellt werden (z . B. https://github.com/fluent/fluent-bit-docker-image/issues/19 ).

In diesem Fall können Sie eine statisch kompilierte Shell kopieren und ausführen, z

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

Aus irgendeinem Grund wird dieser Fehler angezeigt, es sei denn, ich füge den "Bash" -Klärer hinzu. Selbst das Hinzufügen von "#! / Bin / bash" am Anfang meiner Einstiegspunktdatei hat nicht geholfen.

ENTRYPOINT [ "bash", "entrypoint.sh" ]
jenseits der Realität
quelle
@SteveLorimer, ja. Ich habe einen COPYund dann RUN chmod +x /compile_nibbler.shvor dem Entrypoint-Anruf gemacht.
Beyondtheteal
1

Ich hatte das gleiche Problem. Nach vielem googeln konnte ich nicht herausfinden, wie ich es beheben konnte.

Plötzlich bemerkte ich meinen dummen Fehler :)

Wie in den Dokumenten erwähnt , ist der letzte Teil docker runder Befehl, den Sie ausführen möchten, und seine Argumente nach dem Laden des Containers.

NICHT DER BEHÄLTERNAME !!!

Das war mein peinlicher Fehler.

Unten habe ich Ihnen das Bild meiner Befehlszeile zur Verfügung gestellt, um zu sehen, was ich falsch gemacht habe.

Und dies ist das Update, wie in den Dokumenten erwähnt .

Geben Sie hier die Bildbeschreibung ein

Parsa
quelle
-7

Damit es funktioniert, fügen Sie einen weichen Verweis auf / usr / bin hinzu:

ln -s $ (welcher Knoten) / usr / bin / node

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

vacavaca
quelle
1
Bitte fügen Sie eine Beschreibung hinzu, wie es ihm helfen wird.
Mathews Sunny