【问题标题】:docker entrypoint running bash script gets "permission denied"运行 bash 脚本的 docker 入口点得到“权限被拒绝”
【发布时间】:2016-12-17 09:12:23
【问题描述】:

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

三个问题:

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

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

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

谢谢。

【问题讨论】:

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

标签: bash shell docker


【解决方案1】:
  1. “权限被拒绝”会阻止您的脚本被调用。因此,唯一可能相关的语法是第一行的语法(“shebang”),它应该看起来像 #!/usr/bin/env bash#!/bin/bash 或类似的,具体取决于目标的文件系统布局。

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

  3. 出于易于修复先前问题的考虑。


简单的阅读

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 时,它会抛出这样的错误。看起来像是我得到的一个神奇的中间容器。
  • 既不运行 ["chmod", "+x", "/usr/src/app/docker-entrypoint.sh"] 也不运行 ["chmod", "a+x", "/ usr/src/app/docker-entrypoint.sh"] 确实更改了我的 docker 映像中的权限,它仍然是 '-rw-r--r-- '
  • @niid,如果您使用充当minimal reproducible example 的 Dockerfile 创建问题,请随时@-通知我。
【解决方案2】:

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

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

ls -la path/to/directory

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

-rwxrwxr-x

如果没有,请尝试:

chmod +x docker-entrypoint.sh

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

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

【讨论】:

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

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

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

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

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

【讨论】:

  • 这是一种解决方法,但不是一个很好的解决方法——它使用sh 解释脚本,忽略其shebang 的解释器规范;所以如果它使用#!/bin/bash,说它想用bash解释,那将被忽略,而是用sh解释,因此不允许[[ ]]、数组等语言特性。
  • 我已经使用了你的方法并且它奏效了。也许 dos2unix 也能做到这一点
  • 这种方法对我有用。我想知道这背后的原因是什么。
  • 谢谢,为我节省了数小时的研究时间!
  • @CharlesDuffy 什么是正确的解决方案?
【解决方案4】:

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

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

运行ls -al

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

运行
chmod +x docker-entrypoint.sh

在 docker 构建之前!

【讨论】:

    【解决方案5】:

    点 [.]

    这个问题终于花了我3个多小时,我刚试过问题是从最后删除dot

    问题是

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

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

    只需从命令行末尾删除 dot

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:

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

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

          【讨论】:

            【解决方案9】:

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

            sudo chmod 775 docker-entrypoint.sh
            

            【讨论】:

              【解决方案10】:

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

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

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2021-11-18
                • 1970-01-01
                • 2014-02-25
                • 1970-01-01
                • 1970-01-01
                • 2020-05-18
                相关资源
                最近更新 更多