14

Why does Docker mount volume as root, not as user which has run command docker run? Can this be changed by setting some parameters/arguments, etc.?

MWE:

$ ls -la
drwxr-xr-x 2 ubuntu   ubuntu   4096 Aug 22 18:09 shinylog

$ docker run -v $(pwd)/test_dir/:/home/ --name nginx -d nginx
bf340face11485a81ee7c208d490f11abbdc84089ffe9c01d71ffcf8b9ffc27d

$ ls -la
drwxr-xr-x 2 ubuntu   ubuntu   4096 Aug 22 18:09 shinylog
drwxr-xr-x 2 root     root   4096 Aug 22 18:33 test_dir

$ echo $USER
ubuntu

EDIT: After installing docker I encountered error:

Got permission denied while trying to connect to the Docker 
daemon socket at unix:///var/run/docker.sock: Get 
http://%2Fvar%2Frun%2Fdocker.sock/v1.38/containers/json: dial 
unix /var/run/docker.sock: connect: permission denied

and performed:

sudo usermod -a -G docker $USER

Maybe that's the problem?

Taz
  • 5,755
  • 6
  • 26
  • 63
  • This happens because you have added the current user to the docker group. If the current user is root then it will mount as root. Go through the docker setup step – not 0x12 Aug 23 '18 at 04:20
  • @Kalanamith I added `ubuntu` user to `docker` group as suggested here: https://docs.docker.com/install/linux/linux-postinstall/#manage-docker-as-a-non-root-user - and I don't run docker as root. – Taz Aug 23 '18 at 17:09

2 Answers2

5

The docker command is an interface to the rest API of the dockerd daemon. This daemon is what is configuring volumes and performing the tasks to run the container. And in most installs today, this daemon is running as root.

With the host volumes, they are Linux bind mount with an extra feature. Normally with a bind mount, the source directory must already exist. But to improve usability, docker will create this directory for you if it doesn't already exist. It does that from the daemon, that's running as root.

While it may be useful to configure that folder as your current user, there are several challenges. First, the daemon doesn't necessarily know that uid/gid, it's not part of the rest API. Also the daemon isn't necessarily running on your local host, it may be an API call to a remote host. And the user on your host doesn't necessarily match the user in the container.

The ideal solution is to create the directory in advance with the needed permissions and ownership. Or you can switch to named volumes, which have a convenient feature where docker will copy the contents of the image at that location to initialize the volume, including ownership and permissions (this happens when the volume is empty and the container is being created, so it does not receive updates when you have a new image). One last option is to start your container as root, but fix the permissions with an entrypoint script, and then use a command like gosu to change to a non-root user to run the app.

BMitch
  • 231,797
  • 42
  • 475
  • 450
0

The process running nginx is running under root so it is writing the files using the UID of root.

Solution

export UID && docker run -v $(pwd)/test_dir/:/home/ -u=$UID:$UID  --name nginx -d nginx

This will run the nginx process with your local UID and thus write the files with the same user. I have not tested under mac but this is a common solution/setup on linux so it will work for you.

How can you verify if this is working?

Run the nginx with a sleep to make it run for a long time, even if the configuration is wrong.

export UID && docker run -v $(pwd)/test_dir/:/home/ -u $UID:$UID --name nginx -d nginx sleep 3000000000000

Now exec in the container and run whoami to verify the uid of the user. For instance on my machine

docker exec -it nginx /bin/bash
I have no name!@f12fa9c368e6:/$ whoami
whoami: cannot find name for user ID 501
Bizmate
  • 1,835
  • 1
  • 15
  • 19
  • 2
    I've already tried running with argument `-u UID:UID` and `test_dir` still has root owner. – Taz Aug 22 '18 at 19:11
  • What is the UID value you used? Is it the same of echo $UID ? Also remove the container and the folder before re-running the nginx container. I am going to update the answer with a command to verify that it works – Bizmate Aug 22 '18 at 19:26
  • My UID is `id -u` which gives `1000`. – Taz Aug 22 '18 at 19:29
  • Can you run the nginx container with the sleep as shown above and verify the UID inside the container? have you removed the folder? – Bizmate Aug 22 '18 at 19:30
  • `$ whoami whoami: cannot find name for user ID 1000` and `test_dir` is still root owned – Taz Aug 22 '18 at 19:36
  • Could you confirm you removed the folder before rerunning the container with UID ? there is no other way to run files consistently with the right permission other than using UID. IF you are inside the container and run mkdir another_test_folder what are the new folders permissions? – Bizmate Aug 22 '18 at 19:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/178565/discussion-between-taz-and-bizmate). – Taz Aug 22 '18 at 19:44