在Docker容器中进行开发时如何管理权限?

10
在Linux上开发Docker容器时,存在一个权限问题:如何管理主机和容器之间的文件所有权和权限。
假设我有一个运行Ubuntu和Apache服务器的Docker镜像。使用(最新版本的)Apache的默认设置,文档根目录将是“/var/www/html”,而Apache将以“www-data”用户身份运行。
为了进行一些开发工作,我通过Docker将文档根目录暴露出来,并使用“-v /path/to/my/files:/var/www/html”。这就是问题所在:
“/path/to/my/files”中的文件属于容器的“www-data”用户。如果我很幸运,我的主机有一个“www-data”用户,那么它将是该用户;否则,它将是容器本地的不同用户。这些文件的权限通常为“0755”。
因此,当我以自己的名字(称为“jsmith”的用户)进行工作时,由于文件权限和所有权不正确,我无法编辑这些文件。
  • 我可以将文件的所有权更改为jsmith,但这会导致Apache访问文档根目录中的文件时出现问题。

  • 我可以将权限更改为0777,但我在工作过程中创建的任何新文件都将归jsmith所有。

最终结果是必须不断调整开发文件的所有权和权限。其他人必须也面临这个问题,但我看到有关在开发工作流程中使用Docker的主题的帖子似乎都忽略了这个问题。

确实有一个解决方案,但我并不完全满意它:

  • 我在/src/myproject下设置了一个文件夹,其中包含我的开发文件,并由www-data:www-data拥有。

  • 使用BindFS,我将/src/myproject挂载到~/myproject,将www-data:www-data映射到jsmith:jsmith。这使得我可以在~/myproject中编辑文件,而不需要处理权限问题。

  • Apache Docker容器使用-v /src/myproject:/var/www/html挂载/src/myproject目录。Apache看到文件的www-data所有权并没有问题。

这个方法很有效,但似乎过于复杂。其他人是如何解决这个问题的?


你找到其他解决权限问题的方法了吗? - Vail
抱歉,我没有任何建议。我来这里寻找相同的答案 - 你的BindFS提示对我很有帮助。 - jdhildeb
也许 lebokus/docker-volume-bindfs 对你有用。 - k0pernikus
2个回答

1

我意识到我可能太晚了,但这可能对某些人有所帮助。

在您的Dockerfile中,您可以这样做:

RUN usermod -u 1000 www-data
RUN groupmod -g 1000 www-data

这在某些设置中可能有效。


0

我能想到两种解决方案:

第一种是在所有开发者和图像之间使用一个共同的组ID。容器中的UID可能最终会变成数字,但GID将至少提供读取权限,并可选择写入权限,而不必全局分配。在包含目录上使用setgid位,以使文件自动创建为此GID。这不是最干净的方法,可能会导致向其他组成员授予访问权限,但根据您的组织工作流程,这可能更容易管理。

第二个选项是命名卷,我相信这是在您提出这个问题之后添加的。它们允许数据存在于容器已知的UID / GID中。这样做的缺点是将数据移动到内部docker目录中,在容器外部管理起来不太容易。但是,有微服务方法可以使用专用容器(挂载相同的卷)将卷与外部源(git pull,rsync等)同步。您基本上将所有数据的读取和写入都移到容器中,包括任何备份,更新例程和测试脚本。


更新:我经常在开发环境中使用第三个选项,即运行一个入口脚本作为root,将挂载卷的uid/gid与容器内用户的uid/gid进行比较。如果它们不匹配,则会更新容器内用户的uid/gid以匹配主机。这允许开发人员在多个主机上重复使用相同的镜像,其中每个开发人员的uid/gid可能在其位置机器上不同。执行此操作的代码包含在我的bin/fix-perms脚本中,该脚本是我的示例基础镜像的一部分。我的入口脚本的最后一步是使用gosu从root降级到用户,现在具有更改的uid/gid,并且所有编写的文件现在将与主机上的用户匹配。

如果您正在运行MacOS,则最近的一个名为osxfs的功能会自动纠正与主机卷的uid/gid不匹配的问题。


你的第三个选择是我首选的。对我来说,这似乎是最便携的。不过我发现如果挂载的卷中有很多文件,使用chown可能会相当慢。你也有这样的经历吗?你是如何减轻入口点所需的额外时间的? - undefined
减少图像中的文件数量和大小是我所知道的唯一减少递归 chown 时间的选项。每次 chown 都会触发写时复制操作。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接