10

I am trying to understand how to properly add non-root users in docker and give them sudo privileges. Let's say my current Ubuntu 18.04 system has janedoe as a sudo user. I want to create a docker image where I want to add janedoe as a non-root user who can have sudo privileges when needed. Since I new to this Linux system as well as Docker, I typically would appreciate someone explaining through an example how to do this.

The thing that I understand is that whenever I issue the command "USER janedoe" in the Dockerfile, many commands after that line cannot be executed by janedoe's privileges. I would assume we have to add janedoe to a sudo "group" when building the container similar to what we do when an admin adds a new user to the system.

I have been trying to look for some demo Dockerfile explaining the example but couldn't find it.

CS101
  • 444
  • 1
  • 6
  • 21

2 Answers2

14

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:

  1. 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
    
  2. 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 . .
    
  3. 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"]
    
  4. 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).

  5. 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
    
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Useful answer, even just the notion of going back to using root. In my case I had to convince the agent I was running in my CMD block to be fine with being run as root by passing a `AGENT_ALLOW_RUNASROOT` env flag. – insideClaw Nov 16 '22 at 14:21
7

I think you are looking for the answer in this question: How to add users to a docker container

RUN useradd -ms /bin/bash janedoe <-- this command adds the user
usermod -aG sudo janedoe <-- this command tells the container to put the user janedoe inside the SUDO group

Then, if you want to switch to that user for the remainder of the script, use:

USER janedoe <-- all lines after this now use the janedoe user to execute them
WORKDIR /home/janedoe <-- this tells your script from this line on to use paths relative to janedoe's home folder

Since the container itself runs linux modules, most (if not all) linux commands should work inside your container as well. If you have static users (i.e. it's predictable which users), you should be able to create them inside the Dockerfile used to create the image. Now everytime you run a container from said image you should get the janedoe user in there.

JustLudo
  • 1,690
  • 12
  • 29
  • Seriously how is this working? He is asking for root user – user1034912 Mar 10 '23 at 07:38
  • 1
    @user1034912: The first line in OP's post says "I am trying to understand how to properly add NON-ROOT users in docker ". I emphasized the import part for you there. Or is there something I'm missing? – JustLudo Mar 10 '23 at 08:35
  • 1
    Also note: there is a clear distinction between the root user (as in: the user with id 1, default for many linux systems) and a user with sudo rights, which grant basically the same rights but is still not the root user himself. For example; in the log files for activity, all actions done under a normal user are marked as such and can therefor be traced back, like an audit log, even though the user has sudo rights. – JustLudo Mar 10 '23 at 08:38
  • 1
    ok noted. My bad – user1034912 Mar 13 '23 at 01:03