minghua
minghua

Reputation: 6593

Dockerfile replicate the host user UID and GID to the image

Similar to the SO post about replicating UID/GID in container from host but how do you build the image with a user with replicate UID and GID? Preferably, how do you do it with a dockerfile?

I can do it with a bash script:

#!/bin/bash

# current uid and gid
curr_uid=`id -u`
curr_gid=`id -g`

# create bb.dockerfile:
cat << EOF1 > bb.dockerfile
 FROM ubuntu:xenial-20170214
 ARG UNAME=testuser
EOF1

 echo ARG UID=${curr_uid} >> bb.dockerfile
 echo ARG GID=${curr_gid} >> bb.dockerfile

cat << EOF2 >> bb.dockerfile
 RUN groupadd -g \$GID \$UNAME
 RUN useradd -m -u \$UID -g \$GID -s /bin/bash \$UNAME
 USER \$UNAME
 CMD /bin/bash
EOF2

docker build -f bb.dockerfile -t testimg .

This bash will generate a docker file as the following and build on it.

 FROM ubuntu:xenial-20170214
 ARG UNAME=testuser
 ARG UID=1982
 ARG GID=1982
 RUN groupadd -g $GID $UNAME
 RUN useradd -m -u $UID -g $GID -s /bin/bash $UNAME
 USER $UNAME
 CMD /bin/bash

What I'm asking for, is to remove the hardcoded host UID 1982 and GID 1982 from the dockerfile.

Upvotes: 66

Views: 106636

Answers (2)

BMitch
BMitch

Reputation: 263676

You can pass it as a build arg. Your Dockerfile can be static:

FROM ubuntu:xenial-20170214
ARG UNAME=testuser
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID -o $UNAME
RUN useradd -m -u $UID -g $GID -o -s /bin/bash $UNAME
USER $UNAME
CMD /bin/bash

Then you'd pass the options on your build command:

docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) \
  -f bb.dockerfile -t testimg .

Note that I've solved similar problems to this a different way, by running an entrypoint as root that looks a file/directory permissions of the host volume mount, and adjust the uid/gid of the users inside the container to match the volume uid/gid. After making that change, it drops access from the root user to the modified uid/gid user and runs the original command/entrypoint. The result is the image can be run unchanged on any developer machine. An example of this can be found in my jenkins-docker repo:

https://github.com/sudo-bmitch/jenkins-docker

Upvotes: 118

minghua
minghua

Reputation: 6593

Eventually the bb.bash looks like:

#!/bin/bash

# current uid and gid
curr_uid=`id -u`
curr_gid=`id -g`

# create bb.dockerfile:
cat << EOF2 > bb.dockerfile
 FROM ubuntu:xenial-20180417
 ARG UNAME=testuser
 ARG UID=1000
 ARG GID=1000
 RUN groupadd -g \$GID \$UNAME
 RUN useradd -m -u \$UID -g \$GID -s /bin/bash \$UNAME
 USER \$UNAME
 CMD /bin/bash
EOF2    

docker build --build-arg UID=${curr_uid} --build-arg GID=${curr_gid} \
    -f bb.dockerfile -t testimg .

Then another script is to create the container:

#!/bin/bash

docker run -it -d -v $(pwd)/shared:/home/testuser/shared \
    --name testcontainer -P testimg

Upvotes: 0

Related Questions