Linux Docker can';除非有777权限,否则不要写入使用-v装载的目录

Linux Docker can';除非有777权限,否则不要写入使用-v装载的目录,linux,permissions,docker,Linux,Permissions,Docker,我正在使用docker的图像,我需要在其中挂载一个目录,这是我使用-v标志实现的 问题是容器需要写入我装入的目录,但似乎没有这样做的权限,除非我对整个目录执行chmod 777。我不认为将权限设置为允许所有用户对其进行读写是一种解决方案,而只是一种临时解决办法 有谁能指导我找到更规范的解决方案吗 编辑:我一直在运行docker而没有sudo,因为我将自己添加到docker组。我刚刚发现,如果我使用sudo运行docker,问题就解决了,但我很好奇是否还有其他解决方案。最近,在查看了一些docke

我正在使用docker的图像,我需要在其中挂载一个目录,这是我使用
-v
标志实现的

问题是容器需要写入我装入的目录,但似乎没有这样做的权限,除非我对整个目录执行
chmod 777
。我不认为将权限设置为允许所有用户对其进行读写是一种解决方案,而只是一种临时解决办法

有谁能指导我找到更规范的解决方案吗


编辑:我一直在运行docker而没有
sudo
,因为我将自己添加到docker组。我刚刚发现,如果我使用
sudo
运行docker,问题就解决了,但我很好奇是否还有其他解决方案。

最近,在查看了一些docker官方存储库后,我意识到解决这些权限问题更惯用的方法是使用一种称为与入口点脚本配合使用的方法。例如,如果我们以一个现有的docker项目为例,比如solr,就是我之前遇到麻烦的那个项目

OnGithub非常有效地构建了整个项目,但没有考虑权限问题

为了克服这个问题,首先我在dockerfile中添加了gosu设置(如果您实现了这个通知,那么版本
1.4
是硬编码的。您可以查看最新版本)

现在我们可以使用gosu,它基本上与
su
sudo
完全相同,但与docker的配合要更好。根据gosu的说明:

这是一个简单的工具,源于su和sudo具有非常奇怪且通常令人讨厌的TTY和信号转发行为这一简单事实

现在,我对dockerfile所做的其他更改是添加以下行:

COPY solr_entrypoint.sh /sbin/entrypoint.sh
RUN chmod 755 /sbin/entrypoint.sh
ENTRYPOINT ["/sbin/entrypoint.sh"]
只需将我的入口点文件添加到docker容器

以及删除该行:

USER $SOLR_USER
因此,默认情况下,您是根用户。(这就是为什么我们要让gosu从根源上下台)

至于我自己的entrypoint文件,我认为它写得并不完美,但它做到了

#!/bin/bash

set -e

export PS1="\w:\u docker-solr-> "

# step down from root when just running the default start command
case "$1" in
    start)
        chown -R solr /opt/solr/server/solr
        exec gosu solr /opt/solr/bin/solr -f
    ;;
    *)
        exec $@
    ;;
esac
docker运行命令的形式如下:

docker run <flags> <image-name> <passed in arguments>
并以root用户身份运行传递的命令

start
选项首先为solr用户提供目录的所有权,然后运行默认命令。这解决了所有权问题,因为与dockerfile设置不同(dockerfile设置是一次性的),入口点每次都运行

现在,如果我使用-d标志挂载目录,在entrypoint实际运行solr之前,它将在docker容器中为您清理文件


至于这会对容器外的文件造成什么影响,我的结果好坏参半,因为docker在OSX上的行为有点怪异。对我来说,它没有改变容器外部的文件,但在docker能够更好地处理文件系统的另一个操作系统上,它可能会改变容器外部的文件,但是如果您想在容器中装入文件,而不是只是复制文件,我想这就是您必须处理的问题。

映像中的应用程序是作为什么用户运行的?如果它以
solr
用户的身份运行,那么它很可能无法写入主机目录,除非将权限设置为允许
solr
用户(在容器中可以看到uid)写入主机目录。@larsks的这篇文章可能会帮助您设置适当的权限。
docker run <flags> <image-name> <passed in arguments>
docker run <flags> <image-name> start