好吧,我正在运行一个容器,它将创建/修改一些我需要在容器的生命周期之外保留的文件。结果,我为此将一个文件夹放入了容器中:
docker run -v $(pwd)/data:/app/data my-image
在第一次运行时,$(pwd)/data
不存在,因此Docker将为我创建它。但是,它是在用户执行其自己的守护进程(即root
)时创建的。这是有问题的,因为容器内的用户显然不是root
。
为解决此权限问题,我在主机中创建了一个与容器中用户具有相同ID的用户组,并授予他们对$(pwd)/data
父文件夹的访问权限,并添加了组权限文件夹({{1)}上的设置。因此,如果我以root用户身份运行以下命令:
chmod g+s
文件夹sudo mkdir whatver
可以由该组修改,也可以由容器的用户扩展。但是,当Docker创建文件夹whatever
时,它仍然被创建为属于$(pwd)/data
组,并且容器内的用户再次无法修改其中的数据。
现在,我已经通过在运行容器之前制作所需的文件夹来解决此问题。但是,这是一个肮脏的解决方法,我正在寻找一种更清洁的解决方案。还有其他人面对过这个问题吗? Docker是否不尊重父文件夹上的组权限设置是一个问题,还是我在这里丢失了一些东西/做错了什么?
答案 0 :(得分:2)
我不认为首先使文件夹变脏,这对我来说是一种最佳实践。 Docker正在为您运行绑定安装,如果源目录不存在,这将失败。为了用户方便,当您进行主机挂载并且目录丢失时,docker会为您创建此目录,但是无需使用此功能,您会发现其他类型的挂载将不会为您执行目录创建(例如群模式经常使用的--mount
语法。
您可以以root用户身份启动容器,并使用入口点修复目录的权限,然后最后运行诸如exec gosu app_user app_server
之类的内容以从root用户放到用户。我在docker-base图像的入口点执行此操作,这对于开发人员工作流程非常有用,在该工作流程中,开发人员经常需要动态更新容器才能与宿主环境一起工作。
否则,您可以切换到命名卷。它们是新的或为空时,将使用映像的目录内容和权限进行初始化。当您需要持久性但不要求文件系统从主机上的用户直接访问卷内容时,它们是最佳实践。您应该从安装卷的容器内部访问命名卷。