El punto de entrada de Docker que ejecuta el script bash obtiene "permiso denegado"

185

Estoy intentando dockerizar mi aplicación node.js. Cuando el contenedor esté construido, quiero que se ejecute git cloney luego inicie el servidor de nodos. Por lo tanto, pongo estas operaciones en un script .sh. Y ejecute el script como un solo comando en 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"] 

Mi docker-entrypoint.sh se ve así:

git clone [email protected]<repo>.git
git add remote upstream [email protected]<upstream_repo>.git

/usr/bin/node server.js

Después de construir esta imagen y ejecutar:

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

Me estoy poniendo:

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

Entro en el contenedor y el permiso de docker-entrypoint.sh es:

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

tres preguntas:

  1. ¿Mi script bash tiene una sintaxis incorrecta?

  2. ¿Cómo cambio el permiso de un archivo bash antes de agregarlo a una imagen?

  3. ¿Cuál es la mejor manera de ejecutar varios comandos git en el punto de entrada sin usar un script bash?

Gracias.

10
  • Necesitamos ver los permisos del archivo para poder responder a esta pregunta. 10 de agosto de 2016 a las 20:15
  • 2
    Por cierto, si se trata de un script bash , no un script sh , una .shextensión deja una impresión engañosa sobre qué intérpretes pueden ejecutarlo. Podría considerar eliminar eso; no es convencional que los comandos de UNIX tengan extensiones (no se ejecutan ls.elf, por ejemplo). 10/08/2016 a las 20:17
  • ¿Podemos execun caparazón de esa manera? ¿No necesitaría el bashprefijo? 10/08/2016 a las 20:20
  • @ Jean-FrançoisFabre, ¿qué quiere decir exactamente con su pregunta? (No entiendo qué significa "ejecutivo a shell de esa manera", ¿qué significa "de esa manera" en este contexto?) 10/08/2016 a las 20:21
  • 2
    Pregunta tonta, por cierto: ¿son correctos los permisos del script antes de agregarlos a la imagen? 10/08/2016 a las 20:23
271
  1. "Permiso denegado" impide que la secuencia de comandos que se invoque en absoluto . Por lo tanto, la única sintaxis que podría ser pertinente es la de la primera línea (el "shebang"), que debería verse como #!/usr/bin/env bash, o #!/bin/bash, o similar dependiendo del diseño del sistema de archivos de su objetivo.

  2. Lo más probable es que los permisos del sistema de archivos no estén configurados para permitir la ejecución. También es posible que el shebang haga referencia a algo que no es ejecutable, pero esto es mucho menos probable.

  3. Motivado por la facilidad de reparar los problemas anteriores.


La simple lectura de

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

... es que el script no está marcado como ejecutable.

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

abordará esto dentro del contenedor. Alternativamente, puede asegurarse de que la copia local a la que hace referencia el Dockerfile sea ejecutable y luego usarla COPY(que está explícitamente documentada para retener los metadatos).

7
  • Creo que tienes razón. Debería usar COPY en su lugar. Pero parece que todavía necesito cambiar el permiso después de COPIAR el script bash. 10/08/2016 a las 21:14
  • Tengo un archivo phar que crea scripts .bash basados ​​en un comando y luego los elimina una vez que se han completado. Entonces, la necesidad de que los volúmenes compartidos tengan el permiso de ejecución establecido es algo con lo que todavía estoy luchando.
    raupie
    3 de diciembre de 2017 a las 23:19
  • 2
    @raupie, si desea ejecutar un script desde un punto de montaje con la noexecbandera, ejecute en bash yourscriptlugar de ./yourscript. 4 dic 2017 a las 15:55
  • 1
    No lo entiendo, cuando ejecuto docker buildel contenedor inmediato funciona bien. Pero cuando lo hago docker run, arroja tal error. Parece un contenedor intermedio mágico que tengo.
    Tiina
    12 mar 2019 a las 9:58
  • 1
    @niid, si crea una pregunta con un Dockerfile que actúa como un ejemplo mínimo reproducible para el problema, no dude en @ notificarme allí. 21/11/20 a las 21:18
69

Un archivo ejecutable debe tener permisos de ejecución establecidos antes de que pueda ejecutarlo.

En su máquina donde está creando la imagen de la ventana acoplable (no dentro de la imagen de la ventana acoplable en sí) intente ejecutar:

ls -la path/to/directory

La primera columna de la salida de su ejecutable (en este caso, docker-entrypoint.sh) debe tener los bits ejecutables configurados de forma similar a:

-rwxrwxr-x

Si no es así, intente:

chmod +x docker-entrypoint.sh

y luego vuelva a construir su imagen de Docker.

Docker usa su propio sistema de archivos, pero copia todo (incluidos los bits de permisos) de los directorios de origen.

3
  • 23
    chmod +x docker-entrypoint.shen tzhe host es en realidad la solución recomendada, ya que es mucho más simple que cambiar su Dockerfile. 2 de mayo de 2017 a las 19:04
  • Esto funcionó para mí. Realmente no entendí por qué, aunque xD. Si su lector termina en esto en algún momento, agradecería las razones detrás de esto. 22/10/20 a las 11:56
  • si tiene un sistema de archivos compatible con posix (es decir, ejecuta macos o linux o algún bsd), entonces la ventana acoplable copiará los derechos del host. en Windows, por ejemplo, no los tiene, por lo que simplemente los agregará.
    niid
    21/11/20 a las 13:13
34

Enfrenté el mismo problema y lo resolvió

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

Para el Dockerfile en la pregunta original debería ser como:

ENTRYPOINT ["sh", "/usr/src/app/docker-entrypoint.sh"]
6
  • 6
    Esta es una solución alternativa, pero no excelente: interpreta el guión con sh, ignorando la especificación de intérprete de su shebang; así que si usa #!/bin/bash, diciendo que quiere ser interpretado con bash, eso será ignorado y será interpretado en su shlugar, por lo que no se permitirán características del lenguaje como [[ ]], matrices, etc. 11/07/18 a las 10:52
  • 1
    He utilizado su enfoque y funcionó. Quizás también dos2unix haga el truco 8/06/20 a las 10:06
  • Este enfoque es el que funcionó para mí. Me pregunto cuál es la razón detrás de esto. 16 de marzo a las 13:31
  • gracias, ¡ahórrame horas y horas de investigación!
    Kelvin
    28 de marzo a las 5:18
  • @CharlesDuffy ¿Cuál sería la solución correcta en su lugar? 20 de julio a las 20:12
7

Punto [.]

Este problema me llevó más de 3 horas finalmente, solo intenté que el problema era eliminar el punto del final.

el problema era

docker run  -p 3000:80 --rm --name test-con test-app .

/usr/local/bin/docker-entrypoint.sh: 8: exec: .: Permission denied

simplemente elimine el punto del final de su línea de comando:

docker run  -p 3000:80 --rm --name test-con test-app 
3

Esta es una vieja pregunta hecha dos años antes de mi respuesta, voy a publicar lo que funcionó para mí de todos modos.

En mi directorio de trabajo tengo dos archivos: 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

Pude hacer que el archivo en el contenedor de la ventana acoplable fuera ejecutable configurando el archivo fuera del contenedor como ejecutable y chmod 700 provision.shluego ejecutándose docker build ..

3

Esto es quizás un poco estúpido, pero el mensaje de error que recibí fue Permiso denegado y me envió en una dirección muy incorrecta para intentar resolverlo. (Aquí por ejemplo)

Ni siquiera he agregado ningún script bash, creo que la imagen de nodejs que utilizo agrega uno.

FROM node:14.9.0

Estaba ejecutando incorrectamente para exponer / conectar el puerto en mi local:

docker run -p 80:80 [name] . # this is wrong!

lo que da

/usr/local/bin/docker-entrypoint.sh: 8: exec: .: Permission denied

Pero ni siquiera debería tener un punto al final, se agregó a la documentación de la imagen de la ventana acoplable de otro proyecto por error. Simplemente debes ejecutar :

docker run -p 80:80 [name]

Me gusta mucho Docker, pero es triste que tenga tantas trampas como esta y no siempre mensajes de error muy claros ...

2

Si no usa DockerFile, simplemente puede agregar permiso como argumento de línea de comando de bash:

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

El problema se debe a que el archivo original no tiene permiso de ejecución.

Verifique que el archivo original tenga permiso.

correr ls -al

Si el resultado de conseguir -rw-r--r--,

correr
chmod +x docker-entrypoint.s

antes de la construcción de Docker!

1

Otorgar derechos de ejecución al archivo docker-entrypoint.sh

sudo chmod 775 docker-entrypoint.sh
0

Si aún recibe Permission deniederrores cuando intenta ejecutar su script en el punto de entrada de la ventana acoplable, simplemente intente NO usar la forma de shell del punto de entrada:

En lugar de: ENTRYPOINT ./bin/watcherescriba ENTRYPOINT ["./bin/watcher"]:

https://docs.docker.com/engine/reference/builder/#entrypoint

ingrese la descripción de la imagen aquí