'Is it possible to map a user inside the docker container to an outside user?

I know that one can use the --user option with Docker to run a container as a certain user, but in my case, my Docker image has a user inside it, let us call that user manager. Now is it possible to map that user to a user on host? For example, if there is a user john on the host, can we map john to manager?



Solution 1:[1]

Yes, you can set the user from the host, but you should modify your Dockerfile a bit to deal with run time user.

FROM alpine:latest

# Overide user name at build, if buil-arg no passed, will create user named `default` user
ARG DOCKER_USER=default_user

# Create a group and user
RUN addgroup -S $DOCKER_USER && adduser -S $DOCKER_USER -G $DOCKER_USER

# Tell docker that all future commands should run as the appuser user
USER $DOCKER_USER

Now, Build to Docker

docker build --build-arg DOCKER_USER=$(whoami) -t docker_user .

The new user in Docker will be the Host user.

docker run --rm docker_user ash -c "whoami"

Another way just pass the and map the host user without creating the user in Dockerfile.

export UID=$(id -u)
export GID=$(id -g)
docker run -it \
    --user $UID:$GID \
    --workdir="/home/$USER" \
    --volume="/etc/group:/etc/group:ro" \
    --volume="/etc/passwd:/etc/passwd:ro" \
    --volume="/etc/shadow:/etc/shadow:ro" \
    alpine ash -c "whoami"

You can further read more about the user in docker here and here.

Solution 2:[2]

Another way is through an entrypoint.

Example

This example relies on gosu which is present in recent Debian derivatives, not yet in Alpine 3.13 (but is in edge).

You could run this image as follow:

docker run --rm -it \
  --env UID=$(id -u) \
  --env GID=$(id -g) \
  -v "$(pwd):$(pwd)" -w "$(pwd)" \
  imagename
tree
.                          
??? Dockerfile
??? files/
    ??? entrypoint

Dockerfile

FROM ...

# [...]

ARG DOCKER_USER=default_user

RUN addgroup "$DOCKER_USER" \
 && adduser "$DOCKER_USER" -G "$DOCKER_USER"

RUN wget -O- https://github.com/tianon/gosu/releases/download/1.12/gosu-amd64 |\
    install /dev/stdin /usr/local/bin/gosu

COPY files /

RUN chmod 0755 /entrypoint \
 && sed "s/\$DOCKER_USER/$DOCKER_USER/g" -i /entrypoint

ENTRYPOINT ["/entrypoint"]

files/entrypoint

#!/bin/sh
  
set -e
set -u

: "${UID:=0}"
: "${GID:=${UID}}"

if [ "$#" = 0 ]
then set -- "$(command -v bash 2>/dev/null || command -v sh)" -l
fi

if [ "$UID" != 0 ]
then
        usermod -u "$UID" "$DOCKER_USER" 2>/dev/null && {
                groupmod -g "$GID" "$DOCKER_USER" 2>/dev/null ||
                usermod -a -G "$GID" "$DOCKER_USER"
        }
        set -- gosu "${UID}:${GID}" "${@}"
fi

exec "$@"

Notes

  • UID is normally a read-only variable in bash, but it will work as expected if set by the docker --env flag
  • I choose gosu for it's simplicity, but you could make it work with su or sudo; it will need more configuration however
  • if you don't want to specify two --env switch, you could do something like: --env user="$(id -u):$(id -g)" and in the entrypoint: uid=${user%:*} gid=${user#*:}; note at this point the UID variable will be read-only in bash that's why I switched to lower-case... rest of the adaptation is left to the reader

Solution 3:[3]

There is no simple solution that handles all use cases. Solving these problems is continuous work, a part of life in the containerized world.

There is no magical parameter that you could add to a docker exec or docker run invocation and reliably cause the containerized software to no longer run into permissions issues during operations on host-mapped volumes. Unless your mapped directories are not chmod-0777-and-come-what-may, you will be running into permissions issues and you will be solving them as you go, and this is the task you should try becoming efficient at, instead of trying to find a miracle once-and-forever solution that will never exist.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adiii
Solution 2 Kye Russell
Solution 3 Szczepan Ho?yszewski