Switching users inside Docker image to a non-root user

In case you need to perform privileged tasks like changing permissions of folders you can perform those tasks as a root user and then create a non-privileged user and switch to it.

FROM <some-base-image:tag>

# Switch to root user
USER root # <--- Usually you won't be needed it - Depends on base image

# Run privileged command
RUN apt install <packages>
RUN apt <privileged command>

# Set user and group
ARG user=appuser
ARG group=appuser
ARG uid=1000
ARG gid=1000
RUN groupadd -g ${gid} ${group}
RUN useradd -u ${uid} -g ${group} -s /bin/sh -m ${user} # <--- the '-m' create a user home directory

# Switch to user
USER ${uid}:${gid}

# Run non-privileged command
RUN apt <non-privileged command>

You should not use su in a dockerfile, however you should use the USER instruction in the Dockerfile.

At each stage of the Dockerfile build, a new container is created so any change you make to the user will not persist on the next build stage.

For example:

RUN whoami
RUN su test
RUN whoami

This would never say the user would be test as a new container is spawned on the 2nd whoami. The output would be root on both (unless of course you run USER beforehand).

If however you do:

RUN whoami
USER test
RUN whoami

You should see root then test.

Alternatively you can run a command as a different user with sudo with something like

sudo -u test whoami

But it seems better to use the official supported instruction.


As a different approach to the other answer, instead of indicating the user upon image creation on the Dockerfile, you can do so via command-line on a particular container as a per-command basis.

With docker exec, use --user to specify which user account the interactive terminal will use (the container should be running and the user has to exist in the containerized system):

docker exec -it --user [username] [container] bash

See https://docs.docker.com/engine/reference/commandline/exec/

Tags:

Docker

Git

Debian