docker entrypoint exécutant le script bash obtient «permission refusée»


122

J'essaie d'ancrer mon application node.js. Lorsque le conteneur est construit, je veux qu'il exécute un git clone, puis démarre le serveur de nœuds. Par conséquent, j'ai mis ces opérations dans un script .sh. Et exécutez le script en une seule commande dans ENTRYPOINT:

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"] 

Mon docker-entrypoint.sh ressemble à ceci:

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

/usr/bin/node server.js

Après avoir construit cette image et exécutez:

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

Je suis en train:

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

Je shell dans le conteneur et l'autorisation de docker-entrypoint.sh est:

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

trois questions:

  1. Mon script bash a-t-il une syntaxe incorrecte?

  2. Comment modifier l'autorisation d'un fichier bash avant de l'ajouter à une image?

  3. Quelle est la meilleure façon d'exécuter plusieurs commandes git dans entrypoint sans utiliser de script bash?

Merci.


Nous avons besoin de voir les autorisations de fichier pour pouvoir répondre à cette question.
Charles Duffy

BTW, s'il s'agit d'un script bash , pas d'un script sh , une .shextension laisse une impression trompeuse sur les interprètes qui peuvent l'exécuter. Vous pourriez envisager de supprimer cela - il n'est pas conventionnel pour les commandes UNIX d'avoir des extensions (vous ne les exécutez pas ls.elf, par exemple).
Charles Duffy

Pouvons-nous execune coquille de cette façon? n'aurait-il pas besoin du bashpréfixe.
Jean-François Fabre

@ Jean-FrançoisFabre, qu'entendez-vous exactement par votre question? (Je ne comprends pas ce que signifie "exécuter un obus de cette façon" - qu'est-ce que "cette façon" dans ce contexte?)
Charles Duffy

2
Question idiote, au fait - les autorisations du script sont-elles correctes avant de les ajouter à l'image?
Charles Duffy

Réponses:


185
  1. "Autorisation refusée" empêche votre script d'être invoqué du tout . Ainsi, la seule syntaxe qui pourrait être éventuellement pertinente est celle de la première ligne (le "shebang"), qui devrait ressembler à #!/usr/bin/env bash, ou #!/bin/bash, ou similaire selon la disposition du système de fichiers de votre cible.

  2. Très probablement, les autorisations du système de fichiers ne sont pas définies pour permettre l'exécution. Il est également possible que le shebang fasse référence à quelque chose qui n'est pas exécutable, mais c'est beaucoup moins probable.

  3. Mooted par la facilité de réparer les problèmes antérieurs.


La simple lecture de

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

... est que le script n'est pas marqué comme exécutable.

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

abordera ce problème dans le conteneur. Vous pouvez également vous assurer que la copie locale référencée par le Dockerfile est exécutable , puis l'utiliser COPY(qui est explicitement documentée pour conserver les métadonnées).


Je pense que tu as raison. Je devrais utiliser COPY à la place. Mais il semble que j'ai encore besoin de modifier l'autorisation après avoir copié le script bash.
Calvin Hu

J'ai un fichier phar qui crée des scripts .bash basés sur une commande, puis les supprime une fois qu'ils sont terminés. Donc, la nécessité pour les volumes partagés d'avoir le jeu d'autorisations d'exécution est quelque chose avec lequel je me débat encore.
raupie

@raupie, si vous souhaitez exécuter un script à partir d'un point de montage avec l' noexecindicateur, exécutez à la bash yourscriptplace de ./yourscript.
Charles Duffy

1
Je ne sais pas, quand je lance docker buildle conteneur immédiat fonctionne très bien. Mais quand je le fais docker run, cela jette une telle erreur. Cela ressemble à un conteneur intermédiaire magique que j'ai.
Tiina

46

Un fichier exécutable doit disposer d'autorisations d'exécution définies avant de pouvoir l'exécuter.

Dans votre ordinateur sur lequel vous créez l'image Docker (pas à l'intérieur de l'image Docker elle-même), essayez d'exécuter:

ls -la path/to/directory

La première colonne de la sortie de votre exécutable (dans ce cas, docker-entrypoint.sh) doit avoir les bits exécutables définis comme:

-rwxrwxr-x

Sinon, essayez:

chmod +x docker-entrypoint.sh

puis créez à nouveau votre image docker.

Docker utilise son propre système de fichiers, mais il copie tout (y compris les bits d'autorisations) des répertoires source.


13
chmod +x docker-entrypoint.shon tzhe host est en fait la solution recommandée, car elle est beaucoup plus simple que de changer votre fichier Dockerfile.
jotrocken

17

J'ai rencontré le même problème et il a été résolu par

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

Pour le Dockerfile dans la question d'origine, cela devrait ressembler à:

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

5
C'est une solution de contournement, mais pas excellente - cela interprète le script avec sh, ignorant la spécification de son shebang d'un interpréteur; donc s'il utilise #!/bin/bash, en disant qu'il veut être interprété avec bash, cela sera ignoré et il sera interprété avec à la shplace, interdisant ainsi les fonctionnalités de langage telles que les [[ ]]tableaux, etc.
Charles Duffy

J'ai utilisé votre approche et cela a fonctionné. Peut-être que dos2unix fait aussi l'affaire
Wakan Tanka

1

Si vous n'utilisez pas DockerFile, vous pouvez simplement ajouter une autorisation en tant qu'argument de ligne de commande du bash:

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

1

C'est une vieille question posée deux ans avant ma réponse, je vais poster ce qui a fonctionné pour moi de toute façon.

Dans mon répertoire de travail, j'ai deux fichiers: 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

J'ai pu rendre le fichier exécutable dans le conteneur Docker en définissant le fichier en dehors du conteneur comme exécutable chmod 700 provision.shpuis en cours d'exécution docker build ..

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.