Understanding Docker User File Ownership: Avoiding Changing Permissions on Linked Volumes

Consider the following trivial Docker file:

FROM debian:testing RUN adduser --disabled-password --gecos '' docker RUN adduser --disabled-password --gecos '' bob 

in the working directory with nothing else. Create a docker image:

 docker build -t test . 

and then run the bash script in the container by associating the working directory with the new subdirectory in the bob home directory:

 docker run --rm -it -v $(pwd):/home/bob/subdir test 

Who owns the contents of subdir on the container? On the container run:

 cd /home/bob/subdir ls -l 

ad we see:

 -rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile 

Saints smoke! docker owns the content! Returning to the main machine outside the container, we see that our original user still owns the Dockerfile . Try to fix the ownership of the bob home directory. On the container run:

 chown -R bob:bob /home/bob ls -l 

and we see:

 -rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile 

But wait! outside the container, now we run ls -l

 -rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile 

we no longer have our own file. Awful news!




If only one user were added in the above example, everything would be smoother. For some reason, Docker seems to create any home directory that belongs to the first non-root user that it encounters (even if that user is declared in an earlier image). Similarly, this first user is one that matches the same access rights as my home user.

Question 1 Is this correct? Can someone point me to the documentation, I’m just guessing based on the above experiment.

Question 2 . Perhaps this is due only to the fact that both of them have the same numerical value in the kernel, and if I tested the system where my home user was not id 1000 , then permissions could be changed in each case?

Question 3 . The real question, of course, is "what should I do with this?" If bob registered as bob on this host computer, it should be able to run the container as bob and not modify the files in its host account. Be that as it may, he really needs to run the container as a docker user to avoid changing his account.

I heard you ask why I have such a weird Dockerfile? Sometimes I wonder. I am writing a container for webapp (RStudio-server) that allows other users to register, which simply uses the usernames and credentials from the Linux machine as valid usernames. This brings me, perhaps, an unusual motivation to want to create multiple users. I can get around this by creating the user only at runtime, and everything is fine. However, I am using a base image that has added a single docker user so that it can be used interactively but not run as root (according to best practice). This destroys everything, because this user becomes the first user and ends up owning everything, so login attempts as other users fail (the application cannot start due to lack of write permissions). When you run the script run chown , this problem is first solved, but at the cost of related volumes that change permissions (obviously, only a problem if we bind volumes).

+56
linux docker rstudio permissions
Oct 22 '14 at 4:20
source share
3 answers

It is right? Can someone point me to the documentation on this, I’m just guessing based on the above experiment.

Perhaps this is due only to the fact that both of them have the same numerical value for the kernel, and if I tested a system in which my home user was not the identifier 1000, then the permissions will be changed in each case?

Read info coreutils 'chown invocation' , which may give you a better idea of ​​how file permissions / permissions work.

Basically, every file on your computer has a set of bits attached to it, which determines its permissions and ownership. When you chown file, you simply set these bits.

When you chown file for a specific user / group using the username or group, chown will look in /etc/passwd for the username and /etc/group so that the group tries to match the name with the name I would. If the username / group name does not exist in these files, chown will fail.

 root@dc3070f25a13:/test# touch test root@dc3070f25a13:/test# ll total 8 drwxr-xr-x 2 root root 4096 Oct 22 18:15 ./ drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../ -rw-r--r-- 1 root root 0 Oct 22 18:15 test root@dc3070f25a13:/test# chown test:test test chown: invalid user: 'test:test' 

However, you can chown use a file with identifiers no matter what you want (within some upper positive integer bounds, of course), is there a user / group that exists with these identifiers on your computer or not.

 root@dc3070f25a13:/test# chown 5000:5000 test root@dc3070f25a13:/test# ll total 8 drwxr-xr-x 2 root root 4096 Oct 22 18:15 ./ drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../ -rw-r--r-- 1 5000 5000 0 Oct 22 18:15 test 

The UID and GID bits are set in the file itself, so when you mount these files inside the docker container, the file has the same owner / group identifier as on the host, but now maps to /etc/passwd in the container, which will probably be by another user if he does not belong to root (UID 0).

The real question, of course, is "what should I do with this?" If bob is registered as bob on this host computer, it should be able to run the container as bob and not modify the files according to its host account. In its current form, it actually needs to run the container as a user docker to avoid changing its account.

It looks like with your current setup you need to make sure that your UID> usernames in /etc/passwd on your host match your UID> usernames in your containers /etc/passwd if you want to interact with your installed user directory as by the same user who is logged in on the host.

You can create a user with a specific user ID using useradd -u xxxx . Buuuut, this seems like a messy solution ...

You may need to come up with a solution that does not install the host users home directory.

+23
Oct 22 '14 at 18:40
source share
β€” -

Two options I found:

WHY all things (after doing your work)

I did docker run -v `pwd`/shared:/shared image , and the container created the files in pwd/shared that belong to the docker run -v `pwd`/shared:/shared image process. However, /shared still belongs to me. So, in the docker process, I do

chown -R `stat -c "%u:%g" /shared` /shared

stat -c "%u:%g" /shared returns 1000:1000 in my case, being my user’s uid:gid . Although docker conatainer does not have user 1000 , there is an identifier (and stat /shared simply says β€œunknown” if you request a username).

In any case, chown obeys the transfer of /shared content to 1000:1000 (which, as far as this goes, does not exist, but outside the container, it's me). So now I have all the files. The container can still change things if it wants, because from its point of view it is root .

And all is well with the world.

docker run -u , so all created files will automatically have the copyright

Another way to do this is to use the -u flag when launching dockers.

docker run -v `pwd`/shared:/shared -u `stat -c "%u:%g" /shared` ubuntu bash

So the docker user in the youruid:yourgid .

However: this means giving up the root right in the container ( apt-get install , etc.). If you do not create a user with this new uid and add it to the root group.

+49
Apr 11 '15 at 23:20
source share

So, I ended up in this post searching for how to regain ownership of all files (owned by root) that came out of the Docker container running as root to my unprivileged user on the host.

I need the process inside the container to run as root, so I cannot use -u when starting docker.

I'm not proud of what I did, but at the end of my bash script, I added this:

 docker run --rm -it \ --entrypoint /bin/sh \ -e HOST_UID='id -u' \ -v ${HOST_FOLDER_OWNED_BY_ROOT}:/tmp \ alpine:latest \ -c 'chown -R ${HOST_UID}:${HOST_UID} /tmp/' 

Let's parse some lines:

  • Run / bin / sh inside the container:

--entrypoint / bin / sh

  • Pass the current user uid as an environment variable to the container:

-e HOST_UID = id -u

  • Mount any folder that you want to return back to your user (filled with files belonging to the root user, output -ed to the previous container that was running as root) in this new / tmp container:

-v $ {HOST_FOLDER_OWNED_BY_ROOT}: / tmp

  • Run chown recursively with the uid of the host user above the target directory (mounted inside the container in / tmp):

-c 'chown -R $ {HOST_UID}: $ {HOST_UID} / tmp /'

So, with this, I returned the files belonging to my current user, without the need to "elevate" privileges to root or to sudo.

It's dirty, but it worked. Hope I helped.

0
Jan 22 '19 at 22:06
source share



All Articles