Docker入口点运行bash脚本被“拒绝权限”;

我试图dockerize我的node.js应用程序。当容器构建时,我希望它运行git clone,然后启动节点服务器。因此,我将这些操作放在.sh脚本中。并在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"]

我的docker-entrypoint.sh看起来像这样:

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


/usr/bin/node server.js

在构建此映像后运行:

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

我得到:

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

我shell到容器中,docker-entrypoint.sh的权限是:

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

三个问题:

  1. 我的bash脚本有错误的语法吗?

  2. 如何在将bash文件添加到映像之前更改其权限?

  3. 在入口点运行多个git命令而不使用bash脚本的最佳方法是什么?

谢谢。

333069 次浏览
  1. “权限被拒绝”阻止你的脚本被调用在所有。因此,唯一可能相关的语法是第一行的语法(“shebang”),它应该看起来像#!/usr/bin/env bash,或#!/bin/bash,或类似的,这取决于您的目标文件系统布局。

  2. 很可能文件系统权限没有设置为允许执行。也有可能shebang引用了一些不可执行的东西,但这是的可能性较小。

  3. 因为修复之前的问题很容易。


简单的阅读

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

...脚本没有被标记为可执行。

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

将在容器内解决此问题。或者,你可以确保Dockerfile引用的本地副本是可执行的,然后使用COPY(显式记录以保留元数据)。

可执行文件需要具有执行集的权限才能执行。

在你正在构建docker镜像的机器上(不是在docker镜像本身内部)尝试运行:

ls -la path/to/directory

你的可执行文件输出的第一列(在本例中是docker-entrypoint.sh)应该有可执行位设置如下:

-rwxrwxr-x

如果没有,那么试试:

chmod +x docker-entrypoint.sh

然后再次构建docker映像。

Docker使用它自己的文件系统,但它从源目录复制所有内容(包括权限位)。

我也遇到过同样的问题。它通过

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

对于原始问题中的Dockerfile,它应该是这样的:

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

如果你使用DockerFile ,你可以简单地添加权限作为bash的命令行参数:

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

这是一个在我回答这个问题两年前被问到的老问题,无论如何我都要把对我有用的东西贴出来。

在我的工作目录中,我有两个文件: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

我能够使docker容器中的文件可执行,方法是将容器外的文件设置为可执行chmod 700 provision.sh,然后运行docker build .

这可能有点愚蠢,但我得到的错误消息是“许可被拒绝”,它让我在一个非常错误的方向上螺旋式下降,试图解决它。(这里举个例子)

我自己甚至没有添加任何bash脚本,我认为一个是由我使用的nodejs图像添加的。

FROM node:14.9.0

我正在运行错误的来暴露/连接本地的端口:

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

这给了

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

但最后你甚至不应该有一个点,它被错误地添加到另一个项目的docker image文档中。你应该直接跑:

docker run -p 80:80 [name]

我很喜欢Docker,但遗憾的是它有这么多这样的陷阱,而且错误信息并不总是非常清晰……

删除Dot [.]

这个问题与我超过3个小时的最后,我只是尝试了这个问题是在删除从结束只是。

问题是

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

/usr/local/bin/docker-entrypoint.sh: 8: exec: .:权限被拒绝

只需从命令行末尾删除:

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

如果你尝试在docker的入口点运行脚本时仍然得到Permission denied错误,只需尝试使用入口点的壳形式:

< p >代替: ENTRYPOINT ./bin/watcher write ENTRYPOINT ["./bin/watcher"]:

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

enter image description here

该问题是由于原始文件没有执行权限。

检查原始文件是否有权限。

运行ls -al

如果结果为-rw-r--r--

< p >
运行 chmod +x docker-entrypoint.sh < / p >

在docker构建之前!

授予文件docker-entrypoint.sh的执行权限

sudo chmod 775 docker-entrypoint.sh