dockercontainersgem5podman

How to ensure that users inside and outside docker are consistent?


I am making a Docker image. I would like to have a ready-made environment in there as well as some ready-made directories. In this way, I only need to mount some of my directories and use them directly. I made the image using the Dockerfile below. In order to have the same permissions inside and outside the container (not root), I created a user user.

FROM matthewfeickert/docker-python3-ubuntu:latest

USER root
# Create an arbitrary non-root user; we don't care about its uid
# or other properties
RUN useradd --system user

RUN sudo pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

RUN set -x; \
        sudo  apt-get update \
        && DEBIAN_FRONTEND=noninteractive sudo  apt-get install -y  build-essential git-core m4 zlib1g zlib1g-dev libprotobuf-dev protobuf-compiler libprotoc-dev libgoogle-perftools-dev swig xz-utils gdb git \
        && sudo -H python3  -m pip install scons==3.0.1 \
        && sudo -H python3  -m pip install six  


# RUN apt-get -y install gdb

RUN apt-get clean

RUN git config --global url."https://hub.fastgit.xyz/".insteadOf "https://github.com/"

WORKDIR /usr/local/src

RUN git clone https://github.com/gem5/gem5.git

RUN sudo chown user /usr/local/src/gem5 -R

USER user

# RUN mkdir -p /usr/local/src/gem5/build

# RUN sudo chown user /usr/local/src/gem5/build 

WORKDIR /usr/local/src/gem5/

After making the image, I mount my directory into it.

docker run  -it --rm  \
-v my_dir/runScripts:/usr/local/src/gem5/runScripts   \
-v my_dir/gem5/src:/usr/local/src/gem5/src  \
-v my_dir/gem5/configs:/usr/local/src/gem5/configs \
-v my_dir/gem5/programs:/usr/local/src/gem5/programs 
-v my_dir/gem5/build:/usr/local/src/gem5/build  \
-v my_dir/gem5/results:/usr/local/src/gem5/results \
-v my_dir/gem5/update.sh:/usr/local/src/gem5/update.sh  \
--security-opt seccomp=unconfined --user 1000:1000 gerrie/gem5:v1  "/bin/bash"

When I enter the docker container, I output the UID at this time.

$ echo $UID
1000

This is the same as outside the container.

What I think is that the inside and outside of the gem5 directory should be exactly the same user. But it's not.

$ ll
total 232
drwxr-xr-x  1 user   root    4096 Jun 16 09:12 ./
drwxr-xr-x  1 root   root    4096 Jun 16 03:16 ../
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 .git/
-rw-r--r--  1 user   root     984 Jun 16 03:17 .git-blame-ignore-revs
-rw-r--r--  1 user   root     645 Jun 16 03:17 .gitignore
-rw-r--r--  1 user   root   19339 Jun 16 03:17 .mailmap
-rw-r--r--  1 user   root    5595 Jun 16 03:17 CODE-OF-CONDUCT.md
-rw-r--r--  1 user   root   26112 Jun 16 03:17 CONTRIBUTING.md
-rw-r--r--  1 user   root    2332 Jun 16 03:17 COPYING
-rw-r--r--  1 user   root    1478 Jun 16 03:17 LICENSE
-rw-r--r--  1 user   root    7790 Jun 16 03:17 MAINTAINERS.yaml
-rw-r--r--  1 user   root    2133 Jun 16 03:17 README
-rw-r--r--  1 user   root   34435 Jun 16 03:17 RELEASE-NOTES.md
-rwxr-xr-x  1 user   root   28876 Jun 16 03:17 SConstruct*
-rw-r--r--  1 user   root    8616 Jun 16 03:17 TESTING.md
drwxrwxr-x  2 docker docker  4096 Jun 16 08:52 build/
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 build_opts/
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 build_tools/
drwxrwxr-x 13 docker docker  4096 Jun 16 08:54 configs/
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 ext/
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 include/
drwxrwxr-x  2 docker docker  4096 Jun 16 09:03 programs/
-rw-rw-r--  1 docker docker     0 Jun 16 08:58 results
drwxrwxr-x  2 docker docker  4096 Jun 16 02:33 runScripts/
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 site_scons/
drwxrwxr-x 17 docker docker  4096 Jun 16 02:33 src/
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 system/
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 tests/
-rw-rw-r--  1 docker docker     0 Jun 16 08:58 update.sh
drwxr-xr-x  1 user   root    4096 Jun 16 03:17 util/

All the directories I mount belong to the docker user, and all other directories are user. I am able to create files inside my mounted directory. But for gem5's directory, I don't even have permission to create files. But according to the Dockfile, I have clearly chown this directory to user. And when entering the container, I set the uid.

docker@7df3004beb2a:/usr/local/src/gem5$ touch test
touch: cannot touch 'test': Permission denied
docker@7df3004beb2a:/usr/local/src/gem5$ cd runScripts/
docker@7df3004beb2a:/usr/local/src/gem5/runScripts$ touch test
docker@7df3004beb2a:/usr/local/src/gem5/runScripts$ ll
total 8
drwxrwxr-x 2 docker docker 4096 Jun 16 09:13 ./
drwxr-xr-x 1 user   root   4096 Jun 16 09:12 ../
-rw-r--r-- 1 docker docker    0 Jun 16 09:13 test

When I compile, this problem occurs. I think this is caused by a permissions issue. Where did I go wrong? How should I modify it? Thanks a lot!

FileNotFoundError: [Errno 2] No such file or directory: "/usr/local/src/gem5/fatal: unsafe repository ('/usr/local/src/gem5' is owned by someone else)\nTo add an exception for this directory, call:\n\n\tgit config --global --add safe.directory /usr/local/src/gem5/hooks":


Solution

  • As the question was tagged with podman (in addition to docker), here is a Podman solution to the problem of mapping users between the host and the container:

    If you want to map your regular user on the host to a user with the same UID inside the container, you could add the Podman option --userns=keep-id. A more general solution (that also works when the UIDs are not the same) can be found in the troubleshooting.md tip and tip. The tips make use of the options --uidmap and --gidmap. (I wrote those tips).

    The two options --uidmap and --gidmap may look to be a bit complicated to use, but as soon as you understand how rootless Podman maps UIDs and GIDs it will be pretty straight forward.