Logo

How and why to run your Docker apps without root

Understand the importance of running your apps without root privileges inside your Docker container

Published: 25 Oct, 2024


I’ve always been running my containerized apps as root inside inside their containers. So far, nothing bad happened because I haven’t been running any high risk tools in high risk environments. That said, I recently started running my apps without root privileges as a precautionary measure because it’s easy to setup and I don’t want to deal with security incidents.

Why avoid root?

I’ve been using root because it’s simple. I don’t have to worry about permissions inside or outside the container. All operations can be carried out without requiring fine grained privilege escalation inside the container. Processes can simply write to bound volumes as well because root can do anything.

Now that I think about it, the first reason is a bad idea because I don’t want processes to perform all operations without permission. I only want the process to do what’s it’s supposed to do and nothing else. Running as root gives the process too much power.

Permission to write to volumes can easily be implemented by creating a user with the same UID as what’s running inside the container on the host system.

How to do it

First, create an unprivileged user and group on your host system. I use Ansible to automate this process. Look at line 49 in this file for an example. You need to make sure to set both a static user id and a group id because you will use those next.

Next, in your Dockerfile, you will create a user using the same user and group ID you specified above and run your process as this user.

RUN <<_EOF
groupadd -g 700 -r simple_django
useradd -g 700 -u 700 -r simple_django
_EOF

USER simple_django

The username or group name doesn’t matter but make sure the IDs are the same as on the host system.

Now you need to create directories that you want to use a volume inside the container. These directories must be owned by the user running your process. For example:

mkdir /var/my_app
chown -R simple_django:simple_django /var/my_app

docker run --volume /var/my_app:/data my_image

This will bind /var/my_app to /data inside the container. Your process will be able to read and write to it freely because it shares the same UID and GID as on the host system.

Principle of least privilege

Rogue processes who are able to escape containerization are rare in the wild but you might just get unlucky. That’s why it’s a good idea to start running your apps without root privileges even inside your containers now that you know how to do it.


Email me if you have any questions about this post.

Subscribe to the RSS feed to keep updated.