Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

linux

docker

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?

like image 360
MetallicPriest Avatar asked Dec 31 '22 16:12

MetallicPriest


2 Answers

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.

like image 118
Adiii Avatar answered Jan 05 '23 08:01

Adiii


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
like image 35
bufh Avatar answered Jan 05 '23 07:01

bufh