为什么chown在Dockerfile中不起作用?


84

我的Dockerfile创建一个目录,将其chown,然后再列出该目录。该目录仍归root用户所有。这是为什么?

这是Dockerfile:

FROM ubuntu:precise
RUN useradd -d /home/testuser -m -s /bin/bash testuser
RUN mkdir -p /var/local/testrunner/logs
VOLUME ["/var/local/testrunner/logs"]
RUN grep testuser /etc/passwd
RUN grep root /etc/passwd
RUN chown -R testuser:testuser /var/local/testrunner/logs
RUN ls -ld /var/local/testrunner/logs 

这是“ docker build”的输出:

Sending build context to Docker daemon 10.24 kB
Sending build context to Docker daemon 
Step 0 : FROM ubuntu:precise
 ---> ab8e2728644c
Step 1 : RUN useradd -d /home/testuser -m -s /bin/bash testuser
 ---> Using cache
 ---> 640f12671c86
Step 2 : RUN mkdir -p /var/local/testrunner/logs
 ---> Using cache
 ---> bf7756fd5b1f
Step 3 : VOLUME ["/var/local/testrunner/logs"]
 ---> Using cache
 ---> 65c73ee76c20
Step 4 : RUN grep testuser /etc/passwd
 ---> Using cache
 ---> db72fff0b965
Step 5 : RUN grep root /etc/passwd
 ---> Running in ebff78df7a9a
root:x:0:0:root:/root:/bin/bash
 ---> ead0ff704a59
Removing intermediate container ebff78df7a9a
Step 6 : RUN chown -R testuser:testuser /var/local/testrunner/logs
 ---> Running in c925f67b2ab4
 ---> 253132be935e
Removing intermediate container c925f67b2ab4
Step 7 : RUN ls -ld /var/local/testrunner/logs
 ---> Running in 978bc66aa47e
drwxr-xr-x 2 root staff 4096 Oct  1 15:15 /var/local/testrunner/logs

Docker版本1.2.0,构建fa7b24f

该主机运行Ubuntu 12.04,但具有3.13.0-36通用内核。


2
对于COPY后onership问题,请参阅:stackoverflow.com/questions/44766665/...
那巴西盖伊

Answers:


125

回答我自己的问题:它声明为卷。如果取出VOLUME指令,则弦将生效。

而且,如果您运行chown声明了音量,则chown设置仍然有效。


17
“如果在运行chown后声明了音量,则chown设置仍然有效”,这只是回答了我困扰了两天的事情。谢谢!
CashIsClay 2014年

2
对自己说:这里的解释对我来说很有意义container-solutions.com/2014/12/understanding-volumes-docker
MichaelHärtl2015年

4
上面那篇文章的重要一点:“ [在修改卷VOLUMERUN命令后指定了何时],docker足够聪明,可以将卷装载下映像中存在的任何文件复制到卷中并正确设置所有权。这赢得了胜利。如果你指定卷主机目录(使主机文件不会被意外覆盖)“T发生。
Gezim


4
我没有在我的dockerfile上声明任何VOLUME,但仍然存在此问题... :-(
fccoelho

8

该博客http://container42.com/2014/11/03/docker-indepth-volumes/详细解释了此行为。

Dockerfile中的每条指令都会创建一个新容器。该指令对该容器进行了一些更改,并成为一个新层。在VOLUME指令之前,对“ / var / local / testrunner / logs”所做的更改是对实际的容器文件系统进行的。但是,在执行VOLUME指令后,目录“ / var / local / testrunner / logs”是已安装的目录。在VOLUME指令之后对此目录所做的更改将应用​​于已安装的目录,而不是实际的容器文件系统。


2

对于没有卷遇到此问题的任何人,我都发现了一个复杂的解决方案。

问题:

使用一个简单的Dockerfile,如下所示:

FROM ubuntu:16.04
RUN useradd -m -d /home/new_user new_user
COPY test_file.txt /home/new_user
RUN chown -R new_user:new_user /home/new_user
CMD ls -RFlag /home

运行后:

echo "A file to test permissions." > test_file.txt
docker build -t chown-test -f Dockerfile .
docker run --rm -it chown-test

输出为:

/home:
total 12
drwxr-xr-x 1 root 4096 Jun 15 21:37 ./
drwxr-xr-x 1 root 4096 Jun 15 21:39 ../
drwxr-xr-x 1 root 4096 Jun 15 21:39 new_user/

/home/new_user:
total 24
drwxr-xr-x 1 root 4096 Jun 15 21:39 ./
drwxr-xr-x 1 root 4096 Jun 15 21:37 ../
-rw-r--r-- 1 root  220 Aug 31  2015 .bash_logout
-rw-r--r-- 1 root 3771 Aug 31  2015 .bashrc
-rw-r--r-- 1 root  655 Jul 12  2019 .profile
-rw-r--r-- 1 root   28 Jun 11 19:48 test_file.txt

如您所见,文件所有权(例如test_file.txt)仍与user关联root

解:

我发现,如果在chown命令中使用数字UID,则可以更改所有权,但前提是UID不是1000。因此我在UID的UID上加了1 new_user,然后更改了所有权。

FROM ubuntu:16.04
RUN useradd -m -d /home/new_user new_user
# change the uid of new_user to ensure it has whatever it was assigned plus 1 (e.g. if UID was 1000, now it'll be 1001)
RUN id -u new_user | awk '{print $1+1}' | xargs -I{} usermod -u {} new_user
COPY test_file.txt /home/new_user
RUN id -u new_user | xargs -I{} chown -R {}:{} /home/new_user
CMD ls -RFlag /home

运行后:

echo "A file to test permissions." > test_file.txt
docker build -t chown-test -f Dockerfile .
docker run --rm -it chown-test

输出为:

/home:
total 12
drwxr-xr-x 1 root 4096 Jun 15 21:37 ./
drwxr-xr-x 1 root 4096 Jun 15 21:37 ../
drwxr-xr-x 1 1001 4096 Jun 15 21:37 new_user/

/home/new_user:
total 24
drwxr-xr-x 1 1001 4096 Jun 15 21:37 ./
drwxr-xr-x 1 root 4096 Jun 15 21:37 ../
-rw-r--r-- 1 1001  220 Aug 31  2015 .bash_logout
-rw-r--r-- 1 1001 3771 Aug 31  2015 .bashrc
-rw-r--r-- 1 1001  655 Jul 12  2019 .profile
-rw-r--r-- 1 1001   28 Jun 11 19:48 test_file.txt

我不确定为什么首先要遇到这个问题。但是,由于其他人似乎都遇到了这个问题,所以我认为我应该发布解决方法。我的用例是创建一个服务于jupyter笔记本的docker容器。我创建了一个非root用户来服务笔记本。


1

以我的经验,chown安装到根目录(VOLUME /test)时不起作用。使用非根目录位置(VOLUME /var/test)。


0

对于Alpine Linux用户,我必须chown -R root .在自己尝试拥有的工作区中进行操作。这必须CMD在dockerfile中完成,因为我相信卷挂载在挂载时可能会覆盖文件

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.