ChatGPT解决这个技术问题 Extra ChatGPT

运行 bash 脚本的 docker 入口点得到“权限被拒绝”

我正在尝试 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

三个问题:

我的 bash 脚本有错误的语法吗?如何在将 bash 文件添加到图像之前更改其权限?在不使用 bash 脚本的情况下在入口点运行多个 git 命令的最佳方法是什么?

谢谢。

我们需要查看文件权限才能回答这个问题。
顺便说一句,如果这是一个 bash 脚本,而不是一个 sh 脚本,那么 .sh 扩展会让人误解哪些解释器可以执行它。您可能会考虑去掉它——对于 UNIX 命令来说,具有扩展名是不常见的(例如,您不运行 ls.elf)。
我们可以这样exec一个外壳吗?它不需要 bash 前缀。
@Jean-FrançoisFabre,您的问题到底是什么意思? (我不明白“以这种方式执行外壳”是什么意思——在这种情况下“以这种方式”是什么意思?)
顺便提一下,愚蠢的问题——在将脚本添加到图像之前,脚本的权限是否正确?

C
Charles Duffy

“权限被拒绝”完全阻止您的脚本被调用。因此,唯一可能相关的语法是第一行的语法(“shebang”),它应该看起来像 #!/usr/bin/env bash 或 #!/bin/bash 或类似的,具体取决于您的目标的文件系统布局。很可能文件系统权限未设置为允许执行。 shebang 也有可能引用了一些不可执行的东西,但这种可能性要小得多。以易于修复先前的问题为依据。

简单的读法

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(明确记录以保留元数据)。


我想你是对的。我应该改用 COPY 。但似乎我仍然需要在复制 bash 脚本后更改权限。
@raupie,如果您想在带有 noexec 标志的挂载点上运行脚本,请运行 bash yourscript 而不是 ./yourscript
我不明白,当我运行 docker build 时,即时容器工作正常。但是当我做 docker run 时,它会抛出这样的错误。看起来像是我得到的一个神奇的中间容器。
RUN ["chmod", "+x", "/usr/src/app/docker-entrypoint.sh"] 和 RUN ["chmod", "a+x", "/usr/src/app/docker- entrypoint.sh"] 确实更改了我的 docker 映像中的权限,它仍然是 '-rw-r--r-- '
@niid,如果您使用 Dockerfile 作为问题的 minimal reproducible example 创建问题,请随时在此处@-通知我。
S
Sami Start

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

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

ls -la path/to/directory

可执行文件(在本例中为 docker-entrypoint.sh)的输出的第一列应设置可执行位,如下所示:

-rwxrwxr-x

如果没有,请尝试:

chmod +x docker-entrypoint.sh

然后再次构建您的 docker 映像。

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


tzhe 主机上的 chmod +x docker-entrypoint.sh 实际上是推荐的解决方案,因为它比更改 Dockerfile 简单得多。
这对我有用。我真的不明白为什么虽然xD。如果您的读者最终在某个时候遇到这种情况,我将不胜感激这背后的原因。
如果您有 posix 兼容的文件系统(即您运行 macos 或 linux 或某些 bsd),那么您的 docker 将从主机复制权限。例如,在 Windows 上,您没有这些,所以它只会添加它们。
S
Saurabhcdt

我遇到了同样的问题,它解决了

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

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

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

这是一种解决方法,但不是一个很好的解决方法——它使用 sh 解释脚本,忽略其 shebang 的解释器规范;因此,如果它使用 #!/bin/bash,说它想用 bash 解释,那将被忽略,而是用 sh 解释,因此不允许使用 [[ ]]、数组等语言功能。
我用过你的方法,它奏效了。也许 dos2unix 也可以解决问题
这种方法对我有用。我想知道它背后的原因是什么。
谢谢,节省了我数小时的研究时间!
@CharlesDuffy 什么是正确的解决方案?
r
rumbarum

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

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

运行 ls -al

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

运行
chmod +x docker-entrypoint.sh

在 docker 构建之前!


A
Abd Abughazaleh

删除点 [.]

这个问题最终花了我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 

h
helvete

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

sudo chmod 775 docker-entrypoint.sh

B
BradChesney79

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

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

提供.sh:

#!/usr/bin/env bash

yum upgrade

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


O
OZZIE

这可能有点愚蠢,但我收到的错误消息是权限被拒绝,它让我朝着一个非常错误的方向螺旋式下降,试图解决它。 (以这里为例)

我自己什至没有添加任何 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,但很遗憾它有这么多这样的陷阱,而且错误消息并不总是很清楚......


b
betontalpfa

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

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

J
James Bond

如果您尝试在 docker 的入口点运行脚本时仍然遇到 Permission denied 错误,请尝试 DO NOT 使用入口点的 shell 形式

而不是:ENTRYPOINT ./bin/watcherENTRYPOINT ["./bin/watcher"]

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

https://i.stack.imgur.com/TOtR7.png