Docker容器中的用户和文件权限configuration(docker-compose版本3)

Docker 声明它的容器是

“…默认情况下是非常安全的;特别是如果你照顾在容器内运行你的进程作为非特权用户(即非root)”

因此,我试图:

  1. 使用适当处理用户执行的官方图像
  2. 避免在生产中安装主机卷,并使用COPY

当我将代码和configuration文件复制到容器卷中时,所有目录和文件都将创build为“… UID和GID为0”(根拥有者),如文档中所述。

问题:如果文件和目录由root拥有,但是运行的进程是由非root用户拥有,如www-data ,那么是否仍然存在安全风险? 例如,用php-fpm :

 root@7bf71145c18c:/var/www/html# ls -l total 1220 -rw-rw-r-- 1 root root 5931 May 10 12:28 index.php drwxrwxr-x 3 root root 4096 May 10 12:28 logs -rw-rw-r-- 1 root root 28 May 10 12:28 robots.txt root@7bf71145c18c:/var/www/html# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 14:14 ? 00:00:00 php-fpm: master process (/usr/lo www-data 5 1 0 14:14 ? 00:00:00 php-fpm: pool www www-data 6 1 0 14:14 ? 00:00:00 php-fpm: pool www root 7 0 0 14:19 ? 00:00:00 bash root 12 7 0 14:19 ? 00:00:00 ps -ef 

如果是这样,我想知道如何(以及在​​哪里)正确chownchmod我的文件。 从我的研究来看,如果你使用的是docker-compose,那么这看起来就不那么简单了 – 我正在使用docker-compose YAML文件(版本3)和容器特定的Dockerfiles。 看起来,当我在一个容器的Dockerfile结尾时,变化不会生效 – 可能是因为在之后创build了卷(在docker-compose.yml中定义)。 以下是两种configuration的片段:

泊坞窗,compose.yml:

 version: '3' services: fpm: build: ./fpm container_name: "fpm" volumes: - data_volume:/var/www/html ports: - "9000" restart: always volumes: data_volume: 

./fpm Dockerfile:

 FROM php:7-fpm RUN mkdir -p /var/www/html/ COPY . /var/www/html/ RUN find /var -exec chown www-data:www-data {} \; RUN find /var -type d -exec chmod 755 {} \; RUN find /var -type f -exec chmod 644 {} \; 

使用不同的docker-compose版本,很难对各种networking文章,错误修复以及围绕此主题的function请求进行sorting。 我希望在这里得到一些明确的方向/答案,面向docker构成版本3。

问题:如果文件和目录由root拥有,但是运行的进程是由非root用户拥有,如www-data,那么是否仍然存在安全风险?

不是真的。 你可能只需要确保php-fpm已经读取了这些文件的权限。

您正在将/var/www/html的内容复制到映像中,并在构build时设置所有权/权限(Dockerfile)。 还行吧。 这是创build图像的通常用例。

但是你docker-compose.yml挂载到正在运行的容器中,从图像中取代/var/www/html 。 所以,无论你在那个目录中都会隐藏起来。 您将看到安装的音量的内容。

您可能想要select持续存储容器数据所需的策略。 在构build时/var/www/html在大多数情况下可能是可以的。 但是,如果您的应用程序在该目录中的某个位置写入数据,那么您可能会考虑更改该path。 当容器被销毁时,任何写入外挂的数据将会丢失。 所以,请确保yoru应用程序写入从docker-compose.yml作为卷挂载的目录。

docker中的命名卷将被初始化为映像的挂载点的内容。 之后,除非音量完全没有,否则初始化步骤不会再次运行以避免数据丢失。

所以当你第一次创builddata_volume指向/var/www/html ,它获得了该目录的一个副本,包括文件权限。 但是,除非您删除或清空data_volume ,否则对data_volume任何更改都只会更新映像,并且卷将使用该卷的内容覆盖该目录。

如果您不需要data_volume的内容, data_volume可以通过data_volume docker-compose down -v同时删除容器卷。 然后,再次运行docker-compose up -d时,将使用具有新权限的文件创build卷。

如果您确实需要保留data_volume的内容,则可以装入卷并在卷本身上运行命令:

 docker run -it --rm -v $(basename $(pwd))_data_volume:/var/www/html busybox 

上面假设你和docker-compose.yml在同一个文件夹中,而目录是全部小写字符。 否则,请使用$(basename $(pwd))_data_volume docker volume ls显示的卷名replace$(basename $(pwd))_data_volume 。 从上面的容器中,你可以运行你的find命令来更新所有权和权限。