Problem:
I am trying to mount a directory as Docker volume in such a way,
that a user, which is created inside a container could write
into a file in that volume. And at the same time, the file should
be at least readable to my user lape
outside the container.
Essentially, I need to remap a user UID from container user namespace to a specific UID on the host user namespace.
How can I do that?
I would prefer answers that:
Setup:
This is how the situation can be replicated.
I have my Linux user lape
, assigned to docker
group, so I
can run Docker containers without being root.
lape@localhost ~ $ id
uid=1000(lape) gid=1000(lape) groups=1000(lape),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),121(lpadmin),131(sambashare),999(docker)
Dockerfile:
FROM alpine
RUN apk add --update su-exec && rm -rf /var/cache/apk/*
# I create a user inside the image which i want to be mapped to my `lape`
RUN adduser -D -u 800 -g 801 insider
VOLUME /data
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT ["sh", "/entrypoint.sh"]
entrypoint.sh:
#!/bin/sh
chmod 755 /data
chown insider:insider /data
# This will run as `insider`, and will touch a file to the shared volume
# (the name of the file will be current timestamp)
su-exec insider:insider sh -c 'touch /data/$(date +%s)'
# Show permissions of created files
ls -las /data
Once the is built with:
docker build -t nstest
I run the container:
docker run --rm -v $(pwd)/data:/data nstest
The output looks like:
total 8
4 drwxr-xr-x 2 insider insider 4096 Aug 26 08:44 .
4 drwxr-xr-x 31 root root 4096 Aug 26 08:44 ..
0 -rw-r--r-- 1 insider insider 0 Aug 26 08:44 1503737079
So the file seems to be created as user insider
.
From my host the permissions look like this:
lape@localhost ~ $ ls -las ./data
total 8
4 drwxr-xr-x 2 800 800 4096 Aug 26 09:44 .
4 drwxrwxr-x 3 lape lape 4096 Aug 26 09:43 ..
0 -rw-r--r-- 1 800 800 0 Aug 26 09:44 1503737079
Which indicates that the file belongs to uid=800 (that is the insider
user which does not even exist outside the Docker namespace).
Things I tried already:
I tried specifying --user
parameter to docker run
, but it seems it can only map which user on the host is mapped to uid=0 (root) inside the docker namespace, in my case the insider
is not root. So it did not really work in this case.
The only way how I achieved insider
(uid=800) from within container, to be seen as lape(uid=1000) from host, was by adding --userns-remap="default"
to the dockerd
startup script, and adding dockremap:200:100000
to files /etc/subuid
and /etc/subgid
as suggested in documentation for --userns-remap. Coincidentally this worked for me, but it is not sufficient solution, because:
insider
user;If you just need a read access for your user, the simplest will be to add the read permissions for all files and subdirectories in /data
with acls outside of docker.
Add default acl: setfacl -d -m u:lape:-rx /data
.
You will also need to give access to the directory itself: setfacl -m u:lape:-rx /data
.
Are there any obstacles for such a solution?
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