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?
Use a read-only volume At other times, the container only needs read access to the data. Remember that multiple containers can mount the same volume, and it can be mounted read-write for some of them and read-only for others, at the same time.
When building an image, you can't mount a volume. However, you can copy data from another image! By combining this, with a multi-stage build, you can pre-compute an expensive operation once, and re-use the resulting state as a starting point for future iterations.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With