最近,在浏览了一些官方 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,它与 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
所以默认情况下您是 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 可以更好地使用文件系统,它可能会更改你的文件外部,但我想这是你必须处理的,如果你想要将文件挂载到容器中,而不仅仅是复制它们。