Rootless docker host file permissions

207 Views Asked by At

I'm running Docker version 24.0.7, build afdd53b rootless on Ubuntu 22.04. A host folder I mounted to the container read-write is showing up effectively read-only.

On the host:

$ cat /etc/group
...
docker:x:999:gpeterso,mjl
mjl:x:3251:gpeterso

$ cat /etc/subuid
gpeterso:100000:65536
mjl:200000:65536

$ cat /etc/subgid
gpeterso:100000:65536
mjl:200000:65536

$ ls -al /home/gpeterso/mjl-dev/web/logs/
total 8
drwxrwxr-x 2 mjl mjl 4096 Dec 13 11:06 .
drwxrwxr-x 8 mjl mjl 4096 Sep 29 12:59 ..

Then I start the docker container and inspect it:

$ docker inspect mjl-dev-web
[
    {
...
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
...
        "HostConfig": {
            "Binds": [
...
                "/home/gpeterso/mjl-dev/web/logs/:/usr/local/ROOT/logs/",
...
            ],
        "Mounts": [
...
            {
                "Type": "bind",
                "Source": "/home/gpeterso/mjl-dev/web/logs",
                "Destination": "/usr/local/ROOT/logs",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
...
        ],
        "Config": {
...
            "User": "mjl",
...
]

Then I connect to the container and try to access the directory:

$ docker exec -it mjl-dev-web /bin/bash

5af614bba1c8:/usr/local/ROOT$ cd logs

5af614bba1c8:/usr/local/ROOT/logs$ ls -al
total 8
drwxrwxr-x    2 nobody   nobody        4096 Dec 13 11:06 .
drwxr-xr-x    1 root     root          4096 Dec 13 11:20 ..

5af614bba1c8:/usr/local/ROOT/logs$ echo 'hi' >test.txt
bash: test.txt: Permission denied

5af614bba1c8:/usr/local/ROOT$ whoami
mjl

The docker container shows the folder mapped RW (read and write). So I assume it must be a user-mixup? Why is my mapped drive showing up as nobody or root instead of mjl? I tried sudo systemctl restart docker but I'm going to reboot now.

1

There are 1 best solutions below

5
BMitch On

It's not a mixup, it's how user namespaces work. The uid/gid in the container is shifted according to the subuid/subgid entry. So uid/gid 0/0 in the container gets mapped to 200000/200000 on the host. There's no mapping of uid/gid on filesystem mounts, so if uid 200000 doesn't have access to write to the file on the host, uid 0 in the container won't have access to write to the file either.

One workaround is to define a subuid/subgid entry for the container root user that maps back to your host user, e.g. if mjl's uid/gid is 1001, an entry could be added like:

$ cat /etc/subuid
gpeterso:100000:65536
mjl:1001:1
mjl:200000:65535

$ cat /etc/subgid
gpeterso:100000:65536
mjl:1001:1
mjl:200000:65535

And root in the container would map to 1001/1001 on the host.

Another option would be to add a user on the host that matches the host mapped uid/gid that is a member of the group that can write to the folder. That may also need to be done in the container's /etc/group file with the container uid/gid, I'm not sure if the kernel enforces it at both places for bind mounts. In this case, that would involve adding a user to the host for mljcroot, uid/gid 200000/200000, that is a member of the mlj group.