Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker custom user id permissions in a volume (mounted and not mounted)

On the lates MacOS, with Docker for Mac Version 18.06.0-ce-mac70 (26399).

I built an example Docker image that runs as non-root with a custom user created. This is the Dockerfile:

FROM debian:jessie

RUN mkdir /data && \
    groupadd bar && useradd -d /home/foo -g bar -m -s /bin/bash foo && \
    chown foo:bar /data

VOLUME /data

USER foo

ENTRYPOINT ["/bin/bash"]

I built the image. Called it test:1

When I run

docker run -it test:1 -c "ls -la /data"

I see /data is properly owned by user foo:bar.

When I run

docker run -it --user 1717:1818 test:1 -c "ls -la /data; touch /data/test"

I get the a permission error

total 8
drwxr-xr-x 2 foo  bar  4096 Aug 18 18:04 .
drwxr-xr-x 1 root root 4096 Aug 18 18:12 ..
touch: cannot touch '/data/test': Permission denied

If I mount a host directory

docker run -it --user 1717:1818 -v $(pwd)/data:/data test:1 -c "touch /data/test; ls -la /data"

It works without an error!

total 4
drwxr-xr-x 3 1717 1818   96 Aug 18 18:18 .
drwxr-xr-x 1 root root 4096 Aug 18 18:20 ..
-rw-r--r-- 1 1717 1818    0 Aug 18 18:20 test

Now I go into the container to debug

docker run -it --user 1717:1818 test:1

And I'm in a shell. Running a few tests:

I have no name!@75deaf12dcdd:/$ id
uid=1717 gid=1818 groups=1818

I have no name!@75deaf12dcdd:/$ cat /etc/passwd
...
foo:x:1000:1000::/home/foo:/bin/bash

So.. finally to my questions.

  • Why are the permissions of the custom user (--user 1717:1818) applied only on a mounted volume?
  • The important one: Is there a way to apply custom user uid:gid on all files and directories at container execution time (running as non-root)?
like image 509
Eldad Assis Avatar asked Sep 12 '25 00:09

Eldad Assis


2 Answers

A very typical use of an ENTRYPOINT is to have it set to a wrapper script that receives the "real" command as command-line arguments. It does whatever setup it needs to do, then runs the actual command.

#!/bin/sh
chown -R ...
exec "$@"

Then in the same way you can run the base images with just a command line, you can run your own images, without a random -c argument

docker run ubuntu:18.04 ls -l /
docker run test:1 ls -l /

Whatever it is your container usually does, you'd set it as a CMD.

COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
CMD ["my-server", "--foreground"]

If you needed an interactive shell, your entrypoint script gets to do its setup before the actual shell gets launched.

docker run --rm -it test:1 sh

I believe the bind-mounted volume's ownership changing is specifically a feature of Docker for Mac, and it's a consequence of Docker running in a hidden Linux VM that can't directly use the OSX host filesystem. There is some extended discussion in the Docker documentation, more specifically including what happens when a container chowns a file.

like image 141
David Maze Avatar answered Sep 14 '25 14:09

David Maze


The current solution I have working uses the following Dockerfile:

FROM debian:jessie

RUN mkdir /data && \
    groupadd bar && useradd -d /home/foo -g bar -m -s /bin/bash foo && \
    chmod 777 /data

VOLUME /data

USER foo

ENTRYPOINT ["/bin/bash"]

All I did was change the permission on /data to 777 (chmod 777 /data instead of chown foo:bar /data) at build time.
This allowed my container to write to to a mounted /data (that was set to be owned by 1717:1818 on the host).

docker run -it --user 1717:1818 test:1 -c "touch /data/test; ls -la /data"

Now works:

total 8
drwxrwxrwx 2 1717 1818 4096 Aug 21 20:15 .
drwxr-xr-x 1 root root 4096 Aug 21 20:21 ..
-rw-r--r-- 1 1717 1818    0 Aug 21 20:21 test

I'll be happy to hear ideas about ideas to get rid of the 777 on /data

I hope this helps.

like image 20
Eldad Assis Avatar answered Sep 14 '25 14:09

Eldad Assis