Search code examples
linuxdockeruid

Using useradd in a Dockerfile


What happens when a RUN useradd ... command is found in a Dockerfile? Where is that user created? Where does it live? Is it added to the UID pool managed by the kernel? What happens to it when the build context container exits?


Solution

  • A "user" in Linux is a numeric user ID, plus a mapping to some specific user name and other properties in /etc/passwd (optional). There's no such thing as a "uid pool"; if I happen to have user ID 12345 right now then things like filesystem ownership checks do a numeric comparison, and that's kind of the end of it.

    So if a Dockerfile does a RUN useradd, it runs the useradd command, which (among other things) adds an entry to /etc/passwd inside the image's filesystem space. Docker knows to look things up in the image's /etc/passwd file for a Dockerfile USER directive or the docker run -u option. (But you can also use a numeric uid there too.)

    Depending on the host OS and Docker daemon configuration, if you map a host directory into a container with the docker run -v option, either the container process must run as root or with the same numeric user ID as the directory owner to be able to access its files. The name of the respective host and container users is irrelevant.

    The usual best practice I've seen is to do all of the installation as root, then create a single non-root user (its user ID is irrelevant, so long as it's not 0) and make that be the default user when executing the container.

    FROM ubuntu
    
    # Defaults to root; root will own all installed files
    RUN ... && make install
    
    # Set up a non-root user
    RUN useradd myapp
    USER myapp
    
    # Say how to run the container (as user "myapp")
    CMD ["myapp"]