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

Kry*_*ten 7 linux permissions docker

在Linux上的Docker容器中进行开发时,权限存在问题:如何管理主机和容器之间的文件所有权和权限.

想象一下,我有一个运行Ubuntu和Apache服务器的Docker镜像.使用(最新版本)Apache的默认设置,文档根目录将是/var/www/htmlApache,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-datajsmith:jsmith.这允许我编辑文件~/myproject而不必弄乱权限.

  • Apache Docker容器使用安装/src/myproject目录-v /src/myproject:/var/www/html.Apache看到了www-data文件的所有权,没有任何问题.

这很好用,但看起来过于复杂.其他人如何解决这个问题?

BMi*_*tch 0

我可以想到两种解决方案:

在所有开发人员和镜像之间使用通用的组 ID。uid 在容器中最终可能是数字,但 gid 至少会提供读取访问权限,并且可以选择写入访问权限,而不会在全局范围内给出它。在包含的目录上使用 setgid 位可以使用此 gid 自动创建文件。这不是最简洁的方法,可能会导致向其他组成员授予访问权限,但根据组织的工作流程,管理起来可能要容易得多。

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


更新:我经常在开发环境中使用的第三个选项是以 root 身份运行入口点脚本,将已安装的卷 uid/gid 与容器内用户的 uid/gid 进行比较。如果不匹配,容器内用户的 uid/gid 将被更新以匹配主机。这允许开发人员在多个主机上重复使用相同的映像,其中每个开发人员的 uid/gid 在其所在计算机上可能不同。执行此操作的代码包含在我的脚本中,该脚本是我的示例基础映像bin/fix-perms的一部分。我的入口点脚本的最后一步是使用更改后的 uid/gid 从 root 返回到用户,并且所有写入的文件现在将与主机上用户的文件相匹配。gosu

如果您碰巧在 MacOS 上运行,一项名为osxfs 的最新功能会自动纠正与主机卷不匹配的 uid/gid。