How can I add users in a Dockerfile?
When containers were introduced into the game, container images with the user root were often used. Today, it is much better than in the past, but the problem persists, so we need to build an appropriate custom-based image and define a user to execute processes, to avoid security problems and limits application portability.
In this post, we'll look at how to establish a user without root privileges and use it to execute container processes. It's essential to keep in mind that when we made these changes, we faced additional challenges, such as permissions. Root can handle anything, but normal and mortal users cannot!
If you haven't already, I strongly suggest you read the previous post about Docker build and push:
USER instruction
The following Dockerfile begins with root installing some Alpine packages before adding a user called foo to handle the process. Please, no spells! The whoami command displays the current user.
FROM alpine:3.17
WORKDIR /app
USER root
RUN apk --update add curl
RUN adduser -D foo
USER foo
ENTRYPOINT ["whoami"]
- USER root, specifies that the user root will handle all following instructions;
- USER foo, specifies that the user foo will handle all following instructions, so entrypoint will be handled by foo user.
The following command will build a run container.
docker build -t foo-user -f Dockerfile .
docker run -it --rm foo-user
We could come into some challenges! For example, if you have files or directories shared between the host and containers, you should preserve the same UID:GID between them to avoid "hijacking files". If the host or container changes something in the shared context, the user and group will be applied based on where the process is running. As a result, it is critical to maintain the same (UID) and (GID). I published an article on the subject:
More challenges
It is crucial to understand that adduser is a command that may change in syntax according on the Linux distribution used, such as Arch, Debian, RHEL, and others. If we need to utilize usermod as in Debian distros, Alpine should have package shadow installed.
Change user to run the process may be tough but at my workplace, it's common, employ chmod and chown to ensure rights to user responsible for running process and to fix vulnerability container image scanners.
I enjoy using Bitnami container images and recommend that you do as well. They are actively working to remove all root users from any container image in the world, and the container images are routinely updated.
Final thoughts
More can be found on my Github repository. For build images, I made many mixed examples.
In this post, I showed how to build a basic container image without root privileges by utilizing the Dockerfile instruction USER.
Your kernel has already been upgraded; keep your code simple, and God bless 🙏🏿 you.
Time for feedback!