在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容器使用/src/myproject
安装-v /src/myproject:/var/www/html
目录。 Apache看到文件的www-data
所有权,没有任何问题。
这很好用,但看起来过于复杂。其他人如何解决这个问题?
答案 0 :(得分:0)
我可以想到两个解决方案:
在所有开发人员和图片中使用通用组ID。 uid可能最终成为容器中的数字,但gid至少会提供读访问权限,并且可选择写访问权,而不会全局赋予它。使用包含目录上的setgid位来使用此gid自动创建文件。这不是最干净的方法,可能会导致访问其他组成员,但根据组织的工作流程管理可能要容易得多。
第二个选项是命名卷,我相信在您提出这个问题之后会添加这些卷。它们允许您使用容器已知的uid / gid存在数据。这具有将数据移动到内部docker目录的缺点,在容器外部管理它不太容易。但是,有一些微服务方法可以使用安装相同卷的专用容器使卷与外部源(git pull,rsync等)保持同步。您基本上将数据的所有读取和写入移动到容器中,包括任何备份,更新例程和测试脚本。
更新:我经常用于开发环境的第三个选项是以root身份运行入口点脚本,将已装入的卷uid / gid与容器内用户的uid / gid进行比较。如果它们不匹配,则更新容器内用户的uid / gid以匹配主机。这允许开发人员在多个主机上重用相同的映像,其中每个开发人员的uid / gid在他们的位置机器上可能是不同的。执行此操作的代码包含在我的bin/fix-perms
脚本中,该脚本是我的示例base image的一部分。我的入口点脚本的最后一步是使用gosu
从root用户返回给用户,现在使用已更改的uid / gid,所有写入的文件现在将与主机上的用户匹配。
如果您恰好在MacOS上运行,最近一项名为osxfs的功能会自动更正与主机卷的uid / gid不匹配。
答案 1 :(得分:0)
我意识到我很可能为时已晚,但这可能会对某人有所帮助。
在Dockerfile中,您可以执行以下操作:
RUN usermod -u 1000 www-data
RUN groupmod -g 1000 www-data
这可能在某些设置中有效。