Der Docker-Einstiegspunkt, auf dem das Bash-Skript ausgeführt wird, erhält die Berechtigung "verweigert".

121

Ich versuche, meine node.js-App anzudocken. Wenn der Container erstellt ist, soll er a ausführen git cloneund dann den Knotenserver starten. Deshalb habe ich diese Operationen in ein .sh-Skript eingefügt. Führen Sie das Skript als einzelnen Befehl im ENTRYPOINT aus:

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y build-essential libssl-dev gcc curl npm git

#install gcc 4.9
RUN apt-get install -y software-properties-common python-software-properties
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
RUN apt-get update
RUN apt-get install -y libstdc++-4.9-dev

#install newst nodejs
RUN curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
RUN apt-get install -y nodejs

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ADD package.json /usr/src/app/
RUN npm install

ADD docker-entrypoint.sh /usr/src/app/

EXPOSE 8080

ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"] 

Meine docker-entrypoint.sh sieht folgendermaßen aus:

git clone git@<repo>.git
git add remote upstream git@<upstream_repo>.git

/usr/bin/node server.js

Nachdem Sie dieses Image erstellt und ausgeführt haben:

docker run --env NODE_ENV=development -p 8080:8080 -t -i <image>

Ich erhalte:

docker: Error response from daemon: oci runtime error: exec: "/usr/src/app/docker-entrypoint.sh": permission denied.

Ich schalte in den Container und die Erlaubnis von docker-entrypoint.sh ist:

-rw-r--r-- 1 root root 292 Aug 10 18:41 docker-entrypoint.sh

drei Fragen:

  1. Hat mein Bash-Skript eine falsche Syntax?

  2. Wie ändere ich die Berechtigung einer Bash-Datei, bevor ich sie einem Bild hinzufüge?

  3. Was ist der beste Weg, um mehrere Git-Befehle in Entrypoint auszuführen, ohne ein Bash-Skript zu verwenden?

Vielen Dank.

Calvin Hu
quelle
Wir müssen die Dateiberechtigungen sehen, um diese Frage beantworten zu können.
Charles Duffy
Übrigens, wenn dies ein Bash- Skript ist, kein Sh- Skript, .shhinterlässt eine Erweiterung einen irreführenden Eindruck darüber, welche Dolmetscher es ausführen können. Sie könnten in Betracht ziehen, dies herauszunehmen - es ist nicht üblich, dass UNIX-Befehle Erweiterungen haben (Sie werden beispielsweise nicht ausgeführt ls.elf).
Charles Duffy
Können wir so execeine Muschel? würde es nicht das bashPräfix brauchen .
Jean-François Fabre
@ Jean-FrançoisFabre, was genau meinst du mit deiner Frage? (Ich verstehe nicht, was "eine Shell auf diese Weise ausführen" bedeutet - was ist "auf diese Weise" in diesem Zusammenhang?)
Charles Duffy
2
Übrigens eine dumme Frage: Sind die Berechtigungen des Skripts korrekt, bevor Sie sie dem Bild hinzufügen?
Charles Duffy

Antworten:

180
  1. „Zugriff verweigert“ verhindert , dass Ihr Skript aus aufgerufen wird überhaupt . Somit ist die einzige Syntax , die möglicherweise relevant sein könnten , ist , dass von der ersten Zeile (der „Shebang“), die aussehen sollte #!/usr/bin/env bash, oder #!/bin/bash, oder ähnlich je nach Zieldateisystem - Layout.

  2. Höchstwahrscheinlich sind die Dateisystemberechtigungen nicht so festgelegt, dass sie ausgeführt werden können. Es ist auch möglich, dass der Shebang auf etwas verweist, das nicht ausführbar ist, aber dies ist weitaus weniger wahrscheinlich.

  3. Beflügelt von der einfachen Reparatur der vorherigen Probleme.


Das einfache Lesen von

docker: Error response from daemon: oci runtime error: exec: "/usr/src/app/docker-entrypoint.sh": permission denied.

... ist, dass das Skript nicht als ausführbar markiert ist.

RUN ["chmod", "+x", "/usr/src/app/docker-entrypoint.sh"]

wird dies innerhalb des Containers ansprechen. Alternativ können Sie sicherstellen, dass die lokale Kopie, auf die in der Docker-Datei verwiesen wird, ausführbar ist , und diese dann verwenden COPY(die explizit dokumentiert ist, um Metadaten beizubehalten).

Charles Duffy
quelle
Ich glaube, Du hast recht. Ich sollte stattdessen COPY verwenden. Aber es scheint, dass ich die Berechtigung nach dem KOPIEREN des Bash-Skripts noch ändern muss.
Calvin Hu
Ich habe eine Phar-Datei, die .bash-Skripte basierend auf einem Befehl erstellt und sie dann entfernt, sobald sie abgeschlossen sind. Ich habe immer noch Probleme damit, dass für gemeinsam genutzte Volumes die Ausführungsberechtigung festgelegt ist.
raupie
@raupie, wenn Sie ein Skript von einem Mount-Punkt mit dem noexecFlag ausführen möchten , führen Sie bash yourscriptstattdessen aus ./yourscript.
Charles Duffy
1
Ich verstehe nicht, wenn ich docker buildden sofortigen Container laufen lasse, funktioniert einwandfrei. Aber wenn ich das tue docker run, wirft es einen solchen Fehler. Scheint wie ein magischer Zwischenbehälter, den ich habe.
Tiina
46

Für eine ausführbare Datei müssen Berechtigungen für die Ausführung festgelegt sein, bevor Sie sie ausführen können.

Versuchen Sie auf Ihrem Computer, auf dem Sie das Docker-Image erstellen (nicht im Docker-Image selbst), Folgendes auszuführen:

ls -la path/to/directory

In der ersten Spalte der Ausgabe für Ihre ausführbare Datei (in diesem Fall docker-entrypoint.sh) sollten die ausführbaren Bits wie folgt gesetzt sein:

-rwxrwxr-x

Wenn nicht, versuchen Sie:

chmod +x docker-entrypoint.sh

und erstellen Sie dann Ihr Docker-Image erneut.

Docker verwendet ein eigenes Dateisystem, kopiert jedoch alles (einschließlich der Berechtigungsbits) aus den Quellverzeichnissen.

Sami Start
quelle
13
chmod +x docker-entrypoint.shauf dem Host ist eigentlich die empfohlene Lösung, da es viel einfacher ist, als Ihre zu ändern Dockerfile.
Jotrocken
16

Ich hatte das gleiche Problem und es wurde gelöst von

ENTRYPOINT ["sh", "/docker-entrypoint.sh"]

Für das Dockerfile in der ursprünglichen Frage sollte es wie folgt aussehen:

ENTRYPOINT ["sh", "/usr/src/app/docker-entrypoint.sh"]
Saurabhcdt
quelle
5
Dies ist eine Problemumgehung, aber keine großartige - dies interpretiert das Skript mit shund ignoriert die Shebang-Spezifikation eines Interpreters. Wenn es also verwendet #!/bin/bashund sagt, dass es mit Bash interpretiert werden soll, wird dies ignoriert und shstattdessen mit interpretiert , wodurch Sprachfunktionen wie [[ ]]Arrays usw. nicht zugelassen werden.
Charles Duffy
Ich habe Ihren Ansatz verwendet und es hat funktioniert. Vielleicht macht auch dos2unix den Trick
Wakan Tanka
1

Wenn Sie DockerFile nicht verwenden, können Sie einfach die Berechtigung als Befehlszeilenargument der Bash hinzufügen:

docker run -t <image>  /bin/bash -c "chmod +x /usr/src/app/docker-entrypoint.sh; /usr/src/app/docker-entrypoint.sh"
Feindealpfa
quelle
1

Dies ist eine alte Frage, die zwei Jahre vor meiner Antwort gestellt wurde. Ich werde veröffentlichen, was sowieso für mich funktioniert hat.

In meinem Arbeitsverzeichnis befinden sich zwei Dateien: Dockerfile & provision.sh

Dockerfile:

FROM centos:6.8

# put the script in the /root directory of the container
COPY provision.sh /root

# execute the script inside the container
RUN /root/provision.sh

EXPOSE 80

# Default command
CMD ["/bin/bash"]

provision.sh:

#!/usr/bin/env bash

yum upgrade

Ich konnte die Datei im Docker-Container ausführbar machen, indem ich die Datei außerhalb des Containers als ausführbar festlegte und chmod 700 provision.shdann ausführte docker build ..

BradChesney79
quelle