如何影响Dockerfile中RUN命令的顺序?

时间:2016-03-23 16:25:38

标签: linux file docker permissions dockerfile

我正在编写一个Dockerfile,其中root用户创建了一个名为blog的用户来管理网站部署。我使用Docker Hub wordpress容器作为基础。 root用户在/var/www/html下创建文件夹,并为blog用户提供在下面写入的权限。

USER blog之后的下一组RUN命令中,这些命令不会确认blog用户被授予在/var/www/html中写入权限的先前状态。此用户需要在那里克隆git repo,但由于新用户无法在那里写入,我收到错误fatal: could not create leading directories of '/var/www/html/wp-content/uploads': Permission denied,尽管之前为此用户设置了权限。

以下是我用来创建blog用户,将文件复制到其主目录,然后使用该用户克隆回购的命令:

ENV WORDPRESS_DB_USER=wp_blog \
WORDPRESS_DB_NAME=wp_blog \
WORDPRESS_DIR=/var/www/html \
TERM=xterm

# Setup the WordPress site user
# Preliminary command
RUN useradd --create-home --shell /bin/false --groups www-data blog    

COPY id_rsa* known_hosts /home/blog/.ssh/ 
## First set of commands
RUN mkdir --parents "$WORDPRESS_DIR"/wp-content/uploads \
&& chown --recursive blog:blog "$WORDPRESS_DIR" \
&& chown --recursive blog:blog /home/blog

USER blog 
## Second set of commands
RUN chmod u=rw,g=,o= /home/blog/.ssh/id_rsa \
&& chmod u=rw,g=r,o=r /home/blog/.ssh/id_rsa.pub \
&& chmod u=rw,g=r,o=r /home/blog/.ssh/known_hosts \
&& eval $(ssh-agent -s) \
&& ssh-add \
&& export PATH=$PATH:/usr/sbin \

# Use the WordPress user to download the content repo and hooks 
# The following command results in a permissions error:   
&& git clone git@gitlab.com:jb-merideoux/jbm-uploads.git "$WORDPRESS_DIR"/wp-content/uploads \
&& mkdir --parents /home/blog/git/wpgithooks \
&& cd /home/blog/git/wpgithooks \
&& git clone git@github.com:enderandpeter/wpgithooks.git /home/blog/git/wpgithooks \
&& git checkout --git-dir=/home/blog/git/wpgithooks/.git --track origin/wpaddons \
&& chmod u+x /home/blog/git/wpgithooks/*.sh \
&& echo Run the script at /home/blog/git/wpgithooks/setup.sh to get started

blog用户可以为复制的SSH密钥对设置权限,但如果chown --recursive blog:blog /home/blog命令不存在则不能。我认为以前的chown --recursive blog:blog "$WORDPRESS_DIR"命令对blog用户是否可以在/var/www/html中在blog更改权限的同一组命令中写入具有相同的效果在root用户确认root下的所有内容归/home/blog所有后,blog复制到其主页的文件。不知何故,/home/blog的权限在第二组RUN命令中生效,但不在/var/www/html的权限中生效。

仔细检查后,mkdir --parents "$WORDPRESS_DIR"/wp-content/uploads指令似乎没有运行,因为当我在git clone命令之前创建像touch "$WORDPRESS_DIR"/wp-content/uploads/afile这样的文件时,错误是{ {1}}。

当我尝试在touch: cannot touch '/var/www/html/wp-content/uploads/afile': No such file or directory中创建afile时(由于它是由基本wordpress容器创建的,已经存在),我收到错误/var/www/html/,表明{{1}命令未被确认。在第一组RUN语句中的三个命令中,看起来第二组RUN语句中唯一确认的是touch: cannot touch '/var/www/html/afile': Permission denied

我如何编写这个Dockerfile,以便第一个RUN语句中的所有命令都是在新用户执行第二组RUN语句时发出的?

1 个答案:

答案 0 :(得分:0)

哇,那太激烈了。第二组命令永远不会接受事先做过的事情。我已经看到了后续RUN命令知道以前发生的事情的例子,所以我仍然不清楚如何确定。

我找到的解决方案是在第一组命令中使用su,就在root创建目录并设置权限之后:

RUN mkdir --parents "$WORDPRESS_DIR"/wp-content/uploads \
    && chown --recursive blog:blog "$WORDPRESS_DIR" \
    && chown --recursive blog:blog /home/blog \
    && su - blog -s /bin/bash -c '\
        chmod u=rwx,g=,o= /home/blog/.ssh \
        && chmod u=rw,g=,o= /home/blog/.ssh/id_rsa \
...
    && git clone git@gitlab.com:jb-merideoux/jbm-uploads.git '"$WORDPRESS_DIR"'/wp-content/uploads \
...
    && echo '"$WORDPRES_DIR"' setup complete.'

正如您所看到的那样,这是一些疯狂的引用,但幸运的是,您可以完全格式化命令,就像它们被直接提供给Dockerfile一样。我确实在最后使用USER blog做了一些不依赖于早期内容的事情,但我想有时候使用Docker,你必须将一大堆命令串在一起,但我可能会得到所有这些进入一个单独的脚本...