How To Update Docker Image UID/GID User

Many companies with dedicated security team, requires the UID user used by docker images greater than 1000 to avoid conflict with host id. By default, Linux will assign 1000 UID for the first non-root non-system user account.

For docker images that use ENTRYPOINT we need to use the command

# command is command line that available on docker image
docker run --entrypoint COMMAND IMAGE
# example
docker run --entrypoint id  quay.io/keycloak/keycloak:21.1.1

for CMD

docker run IMAGE COMMAND
# example
docker run debian id

Playing with Docker Image

To test some commands or some cases we don’t need to build a new image every time, instead, we access the image/container shell account using root or any other user.

docker run -u root --entrypoint bash  quay.io/keycloak/keycloak:21.1.1
docker run -it -u root debian bash

Building a docker image takes time, so this command saves a lot of time. But remember changes in the shell are only temporary, when you exit the terminal all changes are gone, so keep notes about that.

To verify the current user id use id, lets’s use Keycloak for our example.

$ docker run --entrypoint id  quay.io/keycloak/keycloak:21.1.1
uid=1000(keycloak) gid=0(root) groups=0(root)

Let’s say we’ll update the user to 10000 UID, first thing to do is check the Linux distro and usermod command line, which is useful to manipulate users and groups in Linux.

> docker run -it  --entrypoint bash quay.io/keycloak/keycloak:21.1.1
bash-5.1$ cat /etc/*release
NAME="Red Hat Enterprise Linux"
VERSION="9.1 (Plow)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Red Hat Enterprise Linux 9.1 (Plow)"
ANSI_COLOR="0;31"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:redhat:enterprise_linux:9::baseos"
HOME_URL="https://www.redhat.com/"
DOCUMENTATION_URL="https://access.redhat.com/documentation/red_hat_enterprise_linux/9/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
 
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 9"
REDHAT_BUGZILLA_PRODUCT_VERSION=9.1
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.1"
Red Hat Enterprise Linux release 9.1 (Plow)
Red Hat Enterprise Linux release 9.1 (Plow)
bash-5.1$ usermod
bash: usermod: command not found

From that information we know, Keycloak uses RHEL 9.1, and usermod is not available. Then our other option is to update the UID in /etc/passwd using sed (sed -i 's/1000/10000/g' /etc/passwd). To make the changes permanent, we need to build a new docker image based on the Keycloak docker image.

Create a new folder keycloak-custom-user, add Docker with following lines

FROM quay.io/keycloak/keycloak:21.1.1
USER root
RUN sed -i 's/1000/10000/g' /etc/passwd
USER 10000

then build the docker image

cd keycloak-custom-user
docker build . -t keycloak:21.1.1-atetux1

if you notice from the build command above, I add atetux1 at the end of the docker tag version, the reason was so we understand which base image we use, and atetux1 is the indicator that updates once, hence the number 1.

build docker image custom user

After the new build is done, check the user UID

$ docker run --entrypoint id keycloak:21.1.1-atetux1
uid=10000(keycloak) gid=0(root) groups=0(root)

then run the docker image to make sure it’s working properly. This command is specific for Keycloak

docker run keycloak:21.1.1-atetux1 start-dev

Update UID/GID using usermod groupmod

Let’s take Superset as another example, instead of using some random image we prefer using real-life applications that use by many people and in production.

> docker run apache/superset id
uid=1000(superset) gid=1000(superset) groups=1000(superset)

It uses UID 1000 and GID 1000, if we check the image has usermod and groupmod

which usermod groupmod

check usermod groupmod superset docker image

Create another folder superset-custom-user, create a Dockerfile with following contents

FROM apache/superset                 
USER root
RUN usermod -u 10000 superset && groupmod -g 10000 superset
USER 10000

let’s build the image

cd superset-custom-user
docker build . -t superset:atetux1

then check the UID and GID in our new image

$ docker run superset:atetux1 id
uid=10000(superset) gid=10000(superset) groups=10000(superset)

We intentionally use apache/superset without any tag, to let the user aware that not the proper and recommended way to use the docker image, always stick to a certain tag, for example, apache/superset:2.1.0

Leave a Comment