chmod 在 Docker 中无法正常工作

sto*_*orm 25 permissions chmod docker

我正在为我的Symfony应用程序构建 Docker 映像,我需要授予 apache 服务器写入缓存和日志文件夹的权限

#Dockerfile
FROM php:7-apache

RUN apt-get update \
&& apt-get install -y libicu-dev  freetds-common freetds-bin unixodbc \
&& docker-php-ext-install intl mbstring \
&& a2enmod rewrite

COPY app/php.ini /usr/local/etc/php/
COPY app/apache2.conf /etc/apache2/apache2.conf
COPY ./ /var/www/html

RUN find /var/www/html/ -type d -exec chmod 755 {} \; 
RUN find /var/www/html/ -type f -exec chmod 644 {} \;
RUN chmod -R 777 /var/www/html/app/cache /var/www/html/app/logs
Run Code Online (Sandbox Code Playgroud)

当我docker build -t myname/symfony_apps:latest .使用docker run -p 8080:80 myname/symfony_apps:latest. Apache 日志被权限拒绝错误淹没,我检查过的奇怪的事情ls -a和权限很好。当我从容器的 bash 运行 chmod 时,apache 权限问题消失了,应用程序运行良好

情况

从 dockerfile 运行 chmod 命令:权限已更改,但 apache 仍然抱怨权限被拒绝。 在容器内使用 bash 运行 chmod 相同的命令:权限已更改并且我的应用程序正在运行

任何想法,我是否遗漏了什么,也许我应该在 Dockerfile 的某处添加 root 用户?

mix*_*xel 22

我遇到了同样的问题,如果在一层中创建目录内容而在另一层中更改其权限,则 docker 或 overlay2 中似乎存在一些错误。

作为一种解决方法,您可以将源复制到临时目录:

COPY . /src
Run Code Online (Sandbox Code Playgroud)

然后将其移动到/var/www/html并设置权限(在一个RUN命令中):

RUN rm -rf /var/www/html && mv /src /var/www/html &&\
    find /var/www/html/ -type d -exec chmod 755 {} \; &&\
    find /var/www/html/ -type f -exec chmod 644 {} \; &&\
    chmod -R 777 /var/www/html/app/cache /var/www/html/app/logs
Run Code Online (Sandbox Code Playgroud)

我还创建了GitHub 问题


sec*_*vfr 11

尝试添加:

USER root
Run Code Online (Sandbox Code Playgroud)

它对我有用。

  • 如果您切换到 root,您可能应该在完成后切换回以前的用户,否则您会降低容器的安全性和兼容性。例如,默认情况下,某些 Kubernetes 实现不会以 root 身份运行容器。 (2认同)

小智 8

Docker 中 RUN 的默认 shell 是 /bin/sh,这就是权限设置不正确实际上存在问题的地方。

但是你可以改为只使用 /bin/bash 来轻松修复,注意目录列表前后

Step 7/9 : RUN /bin/bash -c 'ls -la; chmod +x gitlab-properties-builder.sh; ls -la'
---> Running in dc57ae77aa67

drwxr-xr-x. 3 root root      103 Mar  8 17:56 .
drwxr-xr-x. 1 root root       46 Mar  8 17:57 ..
drwxr-xr-x. 2 root root        6 Mar  7 20:47 config
-rw-r--r--. 1 root root     2340 Mar  7 21:20 gitlab-properties-builder.sh
-rw-r--r--. 5 root root 57325770 Mar  5 14:39 gitlab-scm-collector-2.0.5-SNAPSHOT.jar

drwxr-xr-x. 1 root root       42 Mar  8 17:56 .
drwxr-xr-x. 1 root root       61 Mar  8 17:57 ..
drwxr-xr-x. 2 root root        6 Mar  7 20:47 config
-rwxr-xr-x. 1 root root     2340 Mar  7 21:20 gitlab-properties-builder.sh
-rw-r--r--. 5 root root 57325770 Mar  5 14:39 gitlab-scm-collector-2.0.5-SNAPSHOT.jar
---> 8b5de6e348d3
Run Code Online (Sandbox Code Playgroud)

  • 为什么`/bin/bash -c 'chmod +x file'` 有效,而不是`/bin/sh -c 'chmod +x file'`? (5认同)

BMi*_*tch 6

这个问题很可能VOLUME是上游 Dockerfile 内部定义的结果。在 Dockerfile 中定义卷后,您可以使用COPYADD命令将文件直接添加到映像中。但是,RUN一行将:

  • 使用 dockerfile 当前点的镜像定义创建一个临时容器
    • 该临时容器将安装一个匿名卷作为您或在 Dockerfile 中指定的父映像
    • 匿名卷将从图像的内容中初始化
  • 您的命令将在容器内运行
    • 如果在此RUN命令期间列出目录,您将看到已应用的更改,但这些更改已应用于卷
  • 当您的运行命令完成时,docker 将捕获对容器的更改
    • docker diff如果您不删除临时容器,则可以通过 看到这些更改(您可以运行构建以--rm=false保留它们)
    • 这些更改将不包括匿名卷内容,因为它们不存在于临时容器文件系统中,卷是独立的

由于这种行为,您可以选择:

  1. 您可以将文件复制到其他目录并更改那里的权限
  2. 您可以修复主机上的权限,以便直接使用这些权限复制它们
  3. 您可以从您的映像中删除卷,获取上游映像以删除其卷定义,或者您可以在没有卷定义的情况下重建自己的上游映像副本,并以此为基础构建您的映像

请注意,在当前的 php 图像中,卷似乎已被删除,这意味着我们实际上有选项 3。