, our Technical Director, actively uses and promotes Docker. In a new article, he explains how to create users in Docker. The correct way to work with them, why users should not be left with root privileges, and how to solve the issue of mismatched indicators in Dockerfile.
All processes in a container will run as the root user unless specified otherwise. It may seem convenient, as this user has no limitations. This is why working as root is considered unsafe. While no sane person would use root privileges on a local machine, many run processes as root in containers.
There are always bugs that can allow a malicious user to escape from the container and access the host computer. Assuming the worst, we must ensure that processes within the container run under a user with no privileges on the host machine.
Creating a User
Creating a user in a container is no different from creating one in Linux distributions. However, the commands may vary for different base images.
For Debian-based distributions, the Dockerfile needs to include:
RUN groupadd --gid 2000 node
&& useradd --uid 2000 --gid node --shell /bin/bash --create-home nodeFor Alpine:
RUN addgroup -g 2000 node
&& adduser -u 2000 -G node -s /bin/sh -D node
Running processes as a user
To run all subsequent processes as the user with UID 2000, execute:
USER 2000To run all subsequent processes as the node user, execute:
USER nodeMore details in .
Mounting volumes
When mounting volumes into the container, ensure that the user has permission to read and/or write files. For this, the UID (GID) of the user in the container and the user outside the container, who has the corresponding file access rights, must match. The usernames do not matter.
Often, on a Linux computer, the user's UID and GID are both equal to 1000. These identifiers are assigned to the first user on the computer.
You can easily find your identifiers:
idYou will get comprehensive information about your user.
Replace 2000 in the examples with your identifier, and everything will be fine.
Assigning UID and GID to a user
If a user was created earlier but it's necessary to change the identifiers, this can be done as follows:
RUN usermod -u 1000 node
&& groupmod -g 1000 node
If you are using the basic Alpine image, you need to install the shadow package:
RUN apk add --no-cache shadowPassing the user identifier inside the container while building the image
If your identifier matches the identifiers of everyone working on the project, it is sufficient to specify this identifier in the Dockerfile. However, user identifiers often do not match.
How to achieve the desired outcome is not immediately clear. This was the most challenging aspect for me in the process of learning Docker. Many Docker users do not consider that there are different stages in the life of an image. Initially, the image is built using the Dockerfile. When launching a container from the image, the Dockerfile is no longer used.
User creation should occur during the image build. The same applies to defining the user under which the processes will run. This means that we must somehow pass the UID (GID) inside the container.
To use external variables in the Dockerfile, the following directives are used: and . A detailed comparison of directives .
Dockerfile
ARG UID=1000
ARG GID=1000
ENV UID=${UID}
ENV GID=${GID}
RUN usermod -u $UID node
&& groupmod -g $GID node
You can pass arguments via docker-compose like this:
docker-compose
build:
context: ./src/backend
args:
UID: 1000
GID: 1000
P.S. To master all the intricacies of Docker, it is not enough to read documentation or articles. You need to practice a lot, you need to feel Docker.
Source: habr.com
