我正在尝试 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 命令的最佳方法是什么?
谢谢。
.sh
扩展会让人误解哪些解释器可以执行它。您可能会考虑去掉它——对于 UNIX 命令来说,具有扩展名是不常见的(例如,您不运行 ls.elf
)。
exec
一个外壳吗?它不需要 bash
前缀。
“权限被拒绝”完全阻止您的脚本被调用。因此,唯一可能相关的语法是第一行的语法(“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
(明确记录以保留元数据)。
可执行文件需要具有执行集权限才能执行。
在您正在构建 docker 映像的机器中(不在 docker 映像本身内部)尝试运行:
ls -la path/to/directory
可执行文件(在本例中为 docker-entrypoint.sh)的输出的第一列应设置可执行位,如下所示:
-rwxrwxr-x
如果没有,请尝试:
chmod +x docker-entrypoint.sh
然后再次构建您的 docker 映像。
Docker 使用它自己的文件系统,但它从源目录复制所有内容(包括权限位)。
chmod +x docker-entrypoint.sh
实际上是推荐的解决方案,因为它比更改 Dockerfile
简单得多。
我遇到了同样的问题,它解决了
ENTRYPOINT ["sh", "/docker-entrypoint.sh"]
对于原始问题中的 Dockerfile,它应该是:
ENTRYPOINT ["sh", "/usr/src/app/docker-entrypoint.sh"]
sh
解释脚本,忽略其 shebang 的解释器规范;因此,如果它使用 #!/bin/bash
,说它想用 bash 解释,那将被忽略,而是用 sh
解释,因此不允许使用 [[ ]]
、数组等语言功能。
问题是由于原始文件没有执行权限。
检查原始文件是否有权限。
运行 ls -al
如果结果得到 -rw-r--r--
,
运行
chmod +x docker-entrypoint.sh
在 docker 构建之前!
删除点 [.]
这个问题最终花了我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-entrypoint.sh
的执行权限
sudo chmod 775 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"]
提供.sh:
#!/usr/bin/env bash
yum upgrade
通过将容器外的文件设置为可执行文件 chmod 700 provision.sh
然后运行 docker build .
,我能够使 docker 容器中的文件成为可执行文件。
这可能有点愚蠢,但我收到的错误消息是权限被拒绝,它让我朝着一个非常错误的方向螺旋式下降,试图解决它。 (以这里为例)
我自己什至没有添加任何 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,但很遗憾它有这么多这样的陷阱,而且错误消息并不总是很清楚......
如果你不使用 DockerFile,你可以简单地添加权限作为 bash 的命令行参数:
docker run -t <image> /bin/bash -c "chmod +x /usr/src/app/docker-entrypoint.sh; /usr/src/app/docker-entrypoint.sh"
如果您尝试在 docker 的入口点运行脚本时仍然遇到 Permission denied
错误,请尝试 DO NOT 使用入口点的 shell 形式:
而不是:ENTRYPOINT ./bin/watcher
写 ENTRYPOINT ["./bin/watcher"]
:
https://docs.docker.com/engine/reference/builder/#entrypoint
https://i.stack.imgur.com/TOtR7.png
noexec
标志的挂载点上运行脚本,请运行bash yourscript
而不是./yourscript
。docker build
时,即时容器工作正常。但是当我做docker run
时,它会抛出这样的错误。看起来像是我得到的一个神奇的中间容器。