docker entrypoint运行bash脚本获得"权限被拒绝"

时间:2016-08-10 20:11:04

标签: bash shell docker

我试图将我的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.

我进入容器并且docker-entrypoint.sh的权限是:

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

三个问题:

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

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

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

  4. 感谢。

10 个答案:

答案 0 :(得分:113)

  1. &#34;许可被拒绝&#34;阻止您的脚本被调用。因此,唯一可能相关的语法是第一行(&#34; shebang&#34;),它应该看起来像set f [open log.txt a] ; puts $f $msg ; close $f,或#!/usr/bin/env bash,或类似的取决于你的目标的文件系统布局。

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

  3. 为修复先前的问题而轻松修复。

  4. 简单阅读

    #!/bin/bash

    ...是脚本没有标记为可执行文件。

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

    将在容器内解决此问题。或者,您可以确保Dockerfile引用的本地副本是可执行的,然后使用RUN ["chmod", "+x", "/usr/src/app/docker-entrypoint.sh"] (显式记录以保留元数据)。

答案 1 :(得分:28)

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

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

ls -la path/to/directory

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

-rwxrwxr-x

如果没有,请尝试:

chmod +x docker-entrypoint.sh

然后再次构建您的泊坞窗图片。

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

答案 2 :(得分:2)

我遇到同样的问题&amp;它解决了

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

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

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

答案 3 :(得分:2)

点 [.]

这个问题最终困扰了我3个多小时,我刚刚尝试的问题是从末尾删除

问题是

docker run  -p 3000:80 --rm --name test-con test-app .
<块引用>

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

只需从命令行末尾删除 dot

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

答案 4 :(得分:1)

这也许有点愚蠢,但是我得到的错误消息是“权限被拒绝”,这使我向错误的方向盘旋,试图解决它。 (例如)

我自己还没有添加任何bash脚本,我认为我所使用的nodejs图像添加了一个。

cartList

错误地正在运行以公开/连接本地端口:

FROM node:14.9.0

给出

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

但是您甚至不应该在最后加一个点,它是由于错误而添加到另一个项目docker映像的文档中的。 您应该只运行

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

我非常喜欢Docker,但可悲的是它有这么多陷阱,而且错误消息并不总是很清楚...

答案 5 :(得分:1)

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

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

运行ls -al

如果结果得到 -rw-r--r-- ,

运行
chmod +x docker-entrypoint.s

在 docker build 之前!

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

这是一个老问题,在我回答之前两年问过,无论如何我都会发表对我有用的东西。

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

通过将容器外部的文件设置为可执行文件chmod 700 provision.sh然后运行docker build .,我能够使Docker容器中的文件可执行。

答案 8 :(得分:0)

如果尝试在 docker 的入口点运行脚本时仍然出现 Permission denied 错误,请尝试不要使用入口点的 shell 形式 :

代替: ENTRYPOINT ./bin/watcherENTRYPOINT ["./bin/watcher"]

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

enter image description here

答案 9 :(得分:0)

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

sudo chmod 775 docker-entrypoint.sh