在 Windows 主机上的 docker 容器内更改挂载文件夹中的文件权限

Posted

技术标签:

【中文标题】在 Windows 主机上的 docker 容器内更改挂载文件夹中的文件权限【英文标题】:Change file permissions in mounted folder inside docker container on Windows Host 【发布时间】:2018-01-20 00:21:27 【问题描述】:

免责声明/修改 2

几年后,对于阅读此问题的每个人 - 如果您在 Windows 上并希望将 docker 与 linux 容器一起使用,我强烈建议您根本不要在 windows 上使用 docker,而是完全在 VM 中启动整个 docker 环境。这个 Ext3 NTFS 问题会在很多不同的层面上让您感到头疼,以至于安装 docker-machine 甚至可能不值得。


编辑:

我正在使用docker-machine,它在 Virtualbox VM 内启动一个 boot2docker 实例,该实例在 /c/Users 上有一个共享文件夹,您可以从中将卷挂载到容器中。所述卷的权限是问题所在。虚拟机存储在 /c/Users/tom/.docker/ 下

我选择在 Hyper-V 上使用 docker-machine Virtualbox 工作流程,因为我在日常工作流程中需要 VBox,并且由于不同 Hypervisor 之间的不兼容性,不可能在一个系统上同时运行 Hyper-V 和 Virtualbox。

原始问题

我目前正在尝试在 Windows 上的容器中设置 phpMyAdmin,但我无法更改 config.inc.php 文件的权限。

我发现:Cannot call chown inside Docker container (Docker for Windows) 并认为这可能有点相关,但它似乎只适用于 MongoDB。

这是我的 docker-compose.yml

    version: "3"

    services:
      pma:
        image: (secrect company registry)/phpmyadmin
        ports: 
          - 9090:80
        volumes:
          - /c/Users/tom/projects/myproject/data/var/www/public/config.inc.php:/var/www/public/config.inc.php

现在,当我 docker exec -it [container] bash 并更改挂载目录时,我尝试在 config.inc.php 上运行 chmod,但由于某种原因,它静默失败。

root@22a4bag43245: ls -la config.inc.php
-rw------- 1 root root 0 Aug 11 15:11 config.inc.php
root@22a4bag43245: chmod 655 config.inc.php
root@22a4bag43245: ls -la config.inc.php
-rw------- 1 root root 0 Aug 11 15:11 config.inc.php

考虑到链接的答案,我想我可以将卷移出我的 Userhome,但随后 vbox 根本不会安装该文件夹。

如何永久更改/var/www/public/config.inc.php的文件权限?

【问题讨论】:

/c/Users/tom/projects/myproject/data/var/www/public/config.inc.php 是文件还是文件夹? config.inc.php 是一个文件 但是无论是挂载文件夹还是文件作为卷,我都无法更改权限 找到另一个有同样问题的链接:forums.docker.com/t/… 您可能想尝试挂载父目录而不是单个文件。更改 mount 点的权限可能很特别(比如:不可能)。 【参考方案1】:

我遇到了同样的问题,即使在使用 chown 之后也无法更改所有权。正如我researched 一样,这是因为 NTFS 卷安装在 ext 文件系统中。所以我用了另一种方法。

docker 内部的卷没有这些问题。因此,您可以将文件挂载到内部 docker 卷上,然后在本地文件夹中的任意位置创建指向该文件的硬符号链接:

sudo ln $(docker volume inspect --format ' .Mountpoint ' <project_name>_<volume_name>) <absolute_path_of_destination>

通过这种方式,您可以将文件放在所需的位置,在 docker 内并且没有任何权限问题,并且由于硬符号链接,您将能够像在正常卷安装中一样修改文件的内容。

Here 是这个过程的一个工作实现,它挂载和链接一个目录。如果您想了解详细信息,请参阅issue 中的possible fix 部分。

编辑

实施此方法的步骤:

    将相关文件挂载到内部 docker-volume(也称为named volumes)中。

    在进行硬链接之前,请确保卷和相关文件存在于那里。为确保这一点,您应该在之前至少运行一次容器,或者如果您想自动创建此文件,您可以包含一个 docker run 来创建所需的文件并退出。

    docker run --rm -itd \ -v "<Project_name>_<volume_name>:/absolute/path" \ <image> bash -c "touch /absolute/path/<my_file>"

此 docker run 将创建卷和所需文件。这里,container 是我的项目名称,默认情况下,它是项目所在文件夹的名称,&lt;volume_name&gt; 与我们要在原始容器中使用的名称相同。 &lt;image&gt; 可以是已在您的原始容器中使用的同一个。

    在操作系统中创建指向系统上实际文件位置的硬链接。您可以使用docker volume inspect --format ' .Mountpoint ' &lt;project_name&gt;_&lt;volume_name&gt;/&lt;my_file&gt; 找到文件位置。 Linux 用户可以在终端使用ln,Windows 用户可以在命令提示符下使用mklink

在第 3 步中,我们没有使用 /absolute/path,因为 &lt;volume_name&gt; 已经引用了该位置,我们只需要引用该文件即可。

【讨论】:

这种方法看起来很有希望。我会尝试并回复您,谢谢 等等,我无法在我的主机操作系统上进行硬链接,因为它是 Windows。我误会你了吗? 这是针对 linux 操作系统的,对于 Windows,您可以使用 mklink。更多详情here 我使用的不是 Hyper-V,而是 virtualbox 驱动程序和docker-machine。还有机会以某种方式使其正常工作吗? 硬链接不能跨越文件系统边界,因此这不适用于从 Windows > Linux 共享的文件【参考方案2】:

尝试以下方法之一:

    如果可以重建镜像镜像:image: (secrect company registry)/docker-stretchimal-apache2-php7-pma那么在docker文件里面,添加以下内容

    USER root RUN chmod 655 config.inc.php

然后您可以重建映像并将其推送到注册表,您所做的应该可以工作。这应该是您首选的解决方案,因为您不希望每次启动新容器时都手动更改权限

    尝试显式使用root用户执行

    docker exec -it -u root [container] bash

【讨论】:

我无法更改从 Windows 主机挂载到 docker 容器的目录/卷的权限。 AFAIK,1. 将 chmod confic.inc.php inside 图像将被我安装的 confic.inc.php 覆盖。 2. 不工作。即使我-u root,我chmod时权限仍然不会改变。 @TomM 你能提供图片的 docker 文件吗? 不,抱歉。但它也不适用于官方注册表中的图像,所以我怀疑图像有问题 Dockerfile 在挂载卷之前执行(构建),您无法通过这种方式更改挂载卷的权限。

以上是关于在 Windows 主机上的 docker 容器内更改挂载文件夹中的文件权限的主要内容,如果未能解决你的问题,请参考以下文章

如何将安装在主机服务器上的 phpmyadmin 连接到正在运行的 docker 容器内的 maria db? [关闭]

如何从 Windows 主机连接到 wsl2 内的 docker 容器内的应用程序?

多台主机上的 Docker(Windows 和 Ubuntu)

从 Docker 容器中访问主机上的 MySQL 数据库

在同一主机上的不同网络中的 Docker 容器之间进行通信

docker 怎么把宿主机的文件拷贝到运行的容器中