Generally you should think of a Docker container as a wrapper around a single process. If you ask this question about other processes, it doesn't really make sense. (How do I add a user to my PostgreSQL server with sudo privileges? How do I add a user to my Web browser?)
In Docker you almost never need sudo
, for three reasons: it's trivial to switch users in most contexts; you don't typically get interactive shells in containers (how do I get a directory listing from inside the cron daemon?); and if you can run any docker
command at all you can very easily root the whole host. sudo
is also hard to script, and it's very hard to usefully maintain a user password in Docker (writing a root-equivalent password in a plain-text file that can be easily retrieved isn't a security best practice).
In the context of your question, if you've already switched to some non-root user, and you need to run some administrative command, use USER
to switch back to root.
USER janedoe
...
USER root
RUN apt-get update && apt-get install -y some-package
USER janedoe
Since your containers have some isolation from the host system, you don't generally need containers to have the same user names or user IDs as the host system. The exception is when sharing files with the host using bind mounts, but there it's better to specify this detail when you start the container.
The typical practice I'm used to works like this:
In your Dockerfile, create some non-root user. It can have any name. It does not need a password, login shell, home directory, or any other details. Treating it as a "system" user is fine.
FROM ubuntu:18.04
RUN adduser --system --group --no-create-home appuser
Still in your Dockerfile, do almost everything as root. This includes installing your application.
RUN apt-get update && apt-get install ...
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
When you describe the default way to run the container, only then switch to the non-root user.
EXPOSE 8000
USER appuser
CMD ["./main.py"]
Ideally that's the end of the story: your code is built into your image and it stores all of its data somewhere external like a database, so it doesn't care about the host user space at all (there by default shouldn't be docker run -v
or Docker Compose volumes:
options).
If file permissions really matter, you can specify the numeric host user ID to use when you launch the container. The user doesn't specifically need to exist in the container's /etc/passwd
file.
docker run \
--name myapp \
-d \
-p 8000:8000 \
-v $PWD:/data \
-u $(id -u) \
myimage