我试图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脚本的最佳方法是什么?

谢谢。


当前回答

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

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

运行 ls -al

如果result get -rw-r——r——,

运行 Chmod +x docker-entrypoint.sh

在docker构建之前!

其他回答

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

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

在我的工作目录中,我有两个文件: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 .sh,我能够使docker容器中的文件可执行。

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

在你正在构建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"