除非具有777权限,否则Docker无法写入使用-v挂载的目录

m0m*_*eni 7 linux permissions docker

我正在使用docker-solr图像和docker,我需要在其中安装一个目录,我使用该-v标志实现了该目录.

问题是容器需要写入我已挂载到其中的目录,但似乎没有权限这样做,除非我chmod 777在整个目录上执行此操作.我不认为设置允许所有用户读取和写入的权限是解决方案,但只是一个临时的解决方法.

任何人都可以指导我找到更规范的解决方案吗?

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

m0m*_*eni 1

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

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

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

# 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
Run Code Online (Sandbox Code Playgroud)

su现在我们可以使用 gosu,它基本上与或完全相同sudo,但与 docker 配合使用效果更好。从 gosu 的描述来看:

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

现在我对 dockerfile 所做的其他更改是添加这些行:

COPY solr_entrypoint.sh /sbin/entrypoint.sh
RUN chmod 755 /sbin/entrypoint.sh
ENTRYPOINT ["/sbin/entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)

只是为了将我的入口点文件添加到 docker 容器中。

并删除该行:

USER $SOLR_USER
Run Code Online (Sandbox Code Playgroud)

因此默认情况下您是 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
Run Code Online (Sandbox Code Playgroud)

docker run 命令采用以下形式:

docker run <flags> <image-name> <passed in arguments>
Run Code Online (Sandbox Code Playgroud)

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

docker run <flags> <image-name> start
Run Code Online (Sandbox Code Playgroud)

否则运行您以 root 身份传递的命令。

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

因此,现在如果我使用 -d 标志挂载目录,在入口点实际运行 solr 之前,它将为您 chown docker 容器的文件。

至于这对容器外的文件有何影响,我得到了不同的结果,因为 docker 在 OSX 上的行为有点奇怪。对我来说,它没有更改容器外部的文件,但在另一个操作系统上,docker 与文件系统的配合更好,它可能会更改外部的文件,但我想如果您愿意的话,这就是您必须处理的将文件挂载到容器内,而不是仅仅将它们复制进去。