我试图dockerize我的node.js应用程序。当容器构建时,我希望它运行一个git克隆,然后启动节点服务器。因此,我将这些操作放在.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文件添加到映像之前更改其权限? 在入口点运行多个git命令而不使用bash脚本的最佳方法是什么?

谢谢。


当前回答

删除Dot [.]

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

其他回答

我也遇到过同样的问题

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

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

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

"Permission denied" prevents your script from being invoked at all. Thus, the only syntax that could be possibly pertinent is that of the first line (the "shebang"), which should look like #!/usr/bin/env bash, or #!/bin/bash, or similar depending on your target's filesystem layout. Most likely the filesystem permissions not being set to allow execute. It's also possible that the shebang references something that isn't executable, but this is far less likely. Mooted by the ease of repairing the prior issues.


简单的阅读

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

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

我自己甚至没有添加任何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,但遗憾的是它有这么多这样的陷阱,而且错误信息并不总是非常清晰……

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

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

ls -la path/to/directory

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

-rwxrwxr-x

如果没有,那么试试:

chmod +x docker-entrypoint.sh

然后再次构建docker映像。

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

删除Dot [.]

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