【问题标题】:Docker can't write to directory mounted using -v unless it has 777 permissionsDocker 不能写入使用 -v 挂载的目录,除非它具有 777 权限
【发布时间】:2015-11-07 04:56:15
【问题描述】:

我正在使用带有 docker 的 docker-solr 映像,我需要在其中安装一个目录,我使用 -v 标志来实现。

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

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

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

【问题讨论】:

  • 镜像中的应用程序是以什么用户身份运行的?如果它以solr 用户身份运行,那么它很可能无法写入主机目录,除非权限设置为允许solr 用户(在容器内看到uid)写入它。 @larsks 的这个惊人的 answer 可能会帮助您设置适当的权限。

标签: linux permissions docker


【解决方案1】:

最近,在浏览了一些官方 docker 存储库后,我意识到解决这些权限问题的更惯用的方法是使用名为 gosu 的东西与入口点脚本结合使用。例如,如果我们采用一个现有的 docker 项目,例如 solr,与我之前遇到的问题相同。

Github 上的dockerfile 非常有效地构建了整个项目,但没有解决权限问题。

所以为了克服这个问题,首先我将 gosu 设置添加到 dockerfile(如果您实施此通知,则版本 1.4 是硬编码的。您可以检查最新版本 here)。

# grab gosu for easy step-down from root
RUN mkdir -p /home/solr \
    && gpg --keyserver pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
    && curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.4/gosu-$(dpkg --print-architecture)" \
    && curl -o /usr/local/bin/gosu.asc -SL "https://github.com/tianon/gosu/releases/download/1.4/gosu-$(dpkg --print-architecture).asc" \
    && gpg --verify /usr/local/bin/gosu.asc \
    && rm /usr/local/bin/gosu.asc \
    && chmod +x /usr/local/bin/gosu

现在我们可以使用 gosu,它与 susudo 基本完全相同,但与 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

所以默认情况下您是 root 用户。 (这就是为什么我们让 gosu 从 root 下级)。

现在,至于我自己的入口点文件,我认为它写得并不完美,但它完成了工作。

#!/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 run 命令采用以下形式:

docker run <flags> <image-name> <passed in arguments>

基本上,入口点说如果我想像往常一样运行 solr,我们将参数 start 传递到命令的末尾,如下所示:

docker run <flags> <image-name> start

并以其他方式运行您以 root 身份传递的命令。

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

所以现在如果我使用 -d 标志挂载目录,在入口点实际运行 solr 之前,它会为你 docker 容器的 inside 文件。

至于这对容器外的文件有什么影响,我的结果好坏参半,因为 docker 在 OSX 上的行为有点奇怪。对我来说,它并没有更改容器外部的文件,但是在另一个操作系统上,docker 可以更好地使用文件系统,它可能会更改你的文件外部,但我想这是你必须处理的,如果你想要将文件挂载到容器中,而不仅仅是复制它们。

【讨论】:

    猜你喜欢
    • 2014-07-19
    • 2013-07-19
    • 2018-09-07
    • 2010-12-24
    • 1970-01-01
    • 2019-03-13
    • 2019-04-11
    • 2012-01-17
    • 2012-06-13
    相关资源
    最近更新 更多