How to specify userid and groupid for volume mount point on Docker host
Asked Answered
T

1

10

I have been frustrated by this issue for a while because this has been asked multiple times here, such as in How to deal with persistent storage (e.g. databases) in Docker and What is the (best) way to manage permissions for Docker shared volumes?, but the answers do not address the issue at all.

The first "answer" says to just use named volumes instead of traditional bind mounts. That solves nothing because when the named volume is mounted on the host, for instance at the default location /var/lib/docker/volumes/<volume name>/_data, then that mount point will have the uid/gid of the mount point inside the container.

The other "answer" given, before docker had named volumes, was to use a data-only container. This exhibits the same exact problem.

The reason this is a huge problem for me is that I have many embedded machines on which I want to run the docker host, and the user may have a different uid/gid on each of these. Therefore I cannot hardcode a uid/gid in a Dockerfile for the mount points for my persistent volumes, to achieve matching ids.

Here's an example of the problem: Say my user is foo on the host, with uid 1001 and gid 1001, and the user writing files to the volume inside the container has uid 1002. When I run the container, docker will chown 1002:1002 the mount point dir on the host, and write files with this uid, which I can't even read/write with my user foo.

Visually (all these operations on the host):

$ docker volume create --driver local --opt type=volume --opt device=/home/<my_host_user>/logs --opt o=bind logs
logs
$ docker volume inspect logs
[
    {
        "CreatedAt": "2020-08-26T16:26:08+01:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/logs/_data",
        "Name": "logs",
        "Options": {
            "device": "/home/<myhostuser>/logs",
            "o": "bind",
            "type": "volume"
        },
        "Scope": "local"
    }
]
$ pwd
/home/foo
$ mkdir logs && ls -ld logs
drwxr-xr-x 2 foo foo 4096 Aug 26 17:24 logs

Then running the container:

$ docker run --rm --name <cont_name> -it --net="host" --mount src=logs,target=/home/<container_user>/logs <my docker image>

And now the mount point:

$ ls -ld logs
drwxr-xr-x 2 1002 1002 4096 Aug 26 17:30 logs
$ ls -l logs/
total 4
-rw-r----- 1 1002 1002    0 Aug 26 17:30 log
-rw-r----- 1 1002 1002 2967 Aug 26 17:27 log.1

As you can see, the logs written to the volume have a uid/gid which doesn't correspond to something that exists on the host and which I can't access without root/sudo.

Now then, is there ANY way that docker can be told to map uid/gids in the container to uid/gids on the host, or even simpler to just use the specified uid/gid for the host mount point?

Tate answered 26/8, 2020 at 16:49 Comment(1)
You can't specify uid/gid for a mount point; and it's a shame. If you want to mount you are forced with whatever uid/gid your docker-user has (usually 1000:1000).Milanmilanese
S
3

my env:

  1. Ubuntu 22.04
  2. Docker version 20.10.17, build 100c701

create mount piont path with suitable permission.

# docker file 
RUN mkdir --parents '$volumeDir' ; chown --recursive '$userName':'$userGroup' '$volumeDir'

next, create container and mount volume .

# terminal
docker run --name=containerName --interactive  
--user=$userName:$userGroup --mount='source=volumeName,target==$volumeDir,readonly=false'  
imageName /bin/bash

you will got suitable permission

Speight answered 12/7, 2022 at 4:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.