最近,在浏览了一些官方的 docker 存储库后,我意识到解决这些权限问题的更惯用的方法是使用名为gosu https://github.com/tianon/gosu与入口点脚本配合使用。例如,如果我们采用现有的 docker 项目(例如 solr),这与我之前遇到问题的项目相同。
The docker文件 https://github.com/makuk66/docker-solr/blob/master/5.3/DockerfileGithub 上的 非常有效地构建了整个项目,但没有解决权限问题。
因此,为了克服这个问题,首先我将 gosu 设置添加到 dockerfile 中(如果您实现此功能,请注意版本1.4
是硬编码的。您可以检查最新版本here https://github.com/tianon/gosu/releases).
# 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
or 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 身份传递的命令。
The start
option first授予 solr 用户目录所有权,然后运行默认命令。这解决了所有权问题,因为与一次性的 dockerfile 设置不同,入口点每次都会运行。
所以现在如果我使用 -d 标志挂载目录,在入口点实际运行 solr 之前,它将 chown 这些文件inside为您提供 docker 容器。
至于这对容器外的文件有何影响,我得到了不同的结果,因为 docker 在 OSX 上的行为有点奇怪。对我来说,它没有更改容器外部的文件,但在另一个操作系统上,docker 与文件系统的配合更好,它可能会更改外部的文件,但我想如果您愿意的话,这就是您必须处理的将文件挂载到容器内,而不是仅仅将它们复制进去。