【问题标题】:Dockerfile mkdir permission deniedDockerfile mkdir 权限被拒绝
【发布时间】:2021-12-20 07:56:20
【问题描述】:

我正在尝试使用以下方法构建图像:

docker build -t db-demo .

但我明白了

运行 mkdir -p /usr/src/app: #5 0.512 mkdir: 无法创建目录 '/usr/src/app': 权限被拒绝

Dockerfile

FROM mcr.microsoft.com/mssql/server
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY . /usr/src/app
RUN chmod +x /usr/src/app/run-initialization.sh
ENV SA_PASSWORD bpassword
ENV ACCEPT_EULA Y
ENV MSSQL_PID Express
EXPOSE 1433

CMD /bin/bash ./entrypoint.sh

操作系统是Windows。如何解决这个问题?

【问题讨论】:

  • 如果非要我猜的话,我会说:图中的活跃用户不是root,活跃用户没有/usr/src的访问权限。我们可以change the active user 到root,创建我们需要的目录,授予其他用户(我们必须首先识别,例如通过RUN whoami 或通过在运行基础镜像的容器中执行whoami)权限/usr/src/app 然后改回非root用户。
  • 不相关的问题:COPYed 到 /usr/src/app 应该是什么?

标签: bash docker sh


【解决方案1】:

如果我们使用交互式 shell 启动 mssql 容器:

docker run -it --rm mcr.microsoft.com/mssql/server /bin/bash

然后查看容器内的活跃用户:

mssql@ed73727870bb:/$ whoami
mssql

我们看到活跃用户是mssql。此外,如果我们查看容器内/usr/src 的权限:

mssql@ed73727870bb:/$ ls -lisa /usr | grep -i src
163853 4 drwxr-xr-x 2 root root 4096 Apr 15  2020 src

我们看到只有root 对目录/usr/src 具有写访问权限。

因此,如果我们想创建一个目录/usr/src/app,以便用户mssql可以写入它,我们将不得不

  • 将其创建为root 和
  • 向mssql 授予适当的权限。

这导致以下Dockerfile:

FROM mcr.microsoft.com/mssql/server

# change active user to root
USER root 

# create the app directory
RUN mkdir -p /usr/src/app

# set mssql as owner of the app directory
RUN chown mssql /usr/src/app

# change back to user mssql
USER mssql

WORKDIR /usr/src/app

# sanity check: try to write a file
RUN echo "Hello from user mssql" > hello.txt

如果我们构建并运行这个Dockerfile:

docker build -t turing85/my-mssql -f Dockerfile .
docker run -it --rm turing85/my-mssql /bin/bash

我们现在可以看到:

  • 活跃用户仍然是mssql:

    mssql@85e401ccc3f9:/usr/src/app$ whoami
    mssql
    
  • 文件/usr/src/app/hello.txt 已创建,用户mssql 具有读取权限:

    mssql@85e401ccc3f9:/usr/src/app$ cat hello.txt
    Hello from user mssql
    
  • 用户mssql 拥有/usr/src/app 的写入权限:

    mssql@85e401ccc3f9:/usr/src/app$ touch test.txt && ls -lisa
    total 16
    171538 4 drwxr-xr-x 1 mssql root 4096 Nov  6 20:13 .
    171537 8 drwxr-xr-x 1 root  root 4096 Nov  6 20:02 ..
    171539 4 -rw-r--r-- 1 mssql root   17 Nov  6 20:02 hello.txt
    171604 0 -rw-r--r-- 1 mssql root    0 Nov  6 20:13 test.txt
    
  • 用户 mssql 没有对 /usr/src 的写入权限:

    mssql@85e401ccc3f9:/usr/src/app$ touch ../test2.txt
    touch: cannot touch '../test2.txt': Permission denied
    

对帖子中Dockerfile的评论:

似乎我们试图将应用程序复制到mssql 容器中。我假设这样做是为了在 mssql 容器中启动所述应用程序。虽然这是可能的(通过一些配置),但我强烈建议不要使用这种方法。我们可以改为定义两个容器(一个用于数据库,一个用于应用程序),例如通过docker-compose file。

【讨论】:

    【解决方案2】:

    WORKDIR 如果指定目录不存在,则创建它。如果您唯一的权限问题是在尝试创建目录时,您可以删除 RUN mkdir 行并让 Docker 为您创建目录。

    FROM any-base-image
    # Docker creates the directory if it does not exist
    # You do not need to explicitly RUN mkdir
    WORKDIR /usr/src/app
    ...
    

    进一步查看此示例,如果基础映像具有无法访问根目录的非根用户,RUN chmod ... 行也可能会失败。 COPY 也会从主机复制权限,所以如果文件在主机环境中是可执行的,你不需要在它被COPYed 之后显式地chmod +x 它。这样你就可以删除所有的@ 987654328@线;你会留下COPY 和ENV 指令和运行时元数据,它们都不应该遇到权限问题。

    【讨论】:

      猜你喜欢
      • 2016-08-24
      • 2013-07-01
      • 2012-08-13
      • 1970-01-01
      • 2023-03-22
      • 2018-03-19
      • 2015-12-03
      相关资源
      最近更新 更多