As you probably already know, Docker containers typically run with
root privileges by default. This allows for unrestricted container management, which means you can do things like install system packages, edit config files, bind privileged ports, etc. This is really useful for development purposes, but can expose you to high risk once you put your containers into a production environment.
Why? Because anyone who accesses your container running as
root can start undesirable processes in it, such as injecting malicious code. And running a process in your container as root makes it possible to change the user id (UID) or group id (GID) when starting the container, which makes your application vulnerable.
Changing the configuration of your containers to make them run as
non-root adds an extra layer of security. Doing so limits the processes that can be executed and who can execute them. In our quest to continually deliver the latest, most up-to-date and secure applications, Bitnami produces and maintains a selection of non-root image containers - you can find them in our GitHub repository, tagged as "non-root".
In this blog post, I will discuss root and non-root containers in more detail, exploring the difference between the two and the benefits and disadvantages of each. I will also show you an example of how Bitnami creates non-root containers by editing its Dockerfile to change its user permissions and environment variables.
As is explained in the Docker security documentation, running containers and applications with Docker involves running the Docker daemon, and this requires root privileges. Docker needs to have enough permissions to modify the host filesystem to run; otherwise, your container won't be initialized.
But containers don't need to be run as
root user. Moreover, applications, databases, load balancers, etc. shouldn't ever be run as
Why not provide your containers with security from the beginning, by running them as non-root user?
Following the Principle of Least Privilege (PoLP), the main difference between root and non-root containers is that the latter are focused on ensuring the minimum amount of privileges necessary to run a process.
In this sense, root containers offer the following capabilities:
non-root containers regulate which users in which namespaces are able to execute specific processes, what volumes can be accessed, and what ports your container is allowed to access.
The most important advantage to running your containers as non-root is to ensure that your application environment is secure. To put this in perspective, ask yourself this:
"Would I run any process or application as root in my server?" The answer, of course, would be no, right? So why would you do so in your containers?
Running your containers as non-root prevents malicious code from gaining permissions in the container host and means that not just anyone who has pulled your container from the Docker Hub can gain access to everything on your server, for example. If your container gives users privileges, then anyone could run undesired processes, change the UIDs, or gain access to secrets, etc. You will also probably want to work with
non-root containers in a multi-tenant Kubernetes cluster for enforcing security.
While security is the foremost advantage of non-root containers, there are others.
Some Kubernetes distributions, such as Openshift, don't allow you to run containers as root. In the case of Openshift, for example, it runs containers with random UIDs which are not compatible with root containers.
Root-only containers simply do not run in that distro. So running non-root containers enables you to use Kubernetes distributions like Openshift. For more information on this, check out the following post about Running Non-Root Containers on Openshift
Bitnami maintains a catalog of more than 80 containers. Some of the infrastructure containers have been released as
These are some of the Docker containers that Bitnami has released as
But there are many more Bitnami containers available with non-root privileges. To view all of them, take a look at those tagged as
non-root in the Bitnami GitHub repository.
Let me now explain what tweaks Bitnami made to transform a root container into a non-root container. To do so, I will use the Bitnami Redis Docker image.
If you check its Dockerfile you will find something similar to this:
The image above shows three lines highlighted; I am going to explain the meaning and behavior of each:
BITNAMI_PKG_CHMODenv var defines the file permissions for the folders: write, read or execute.
../libcomponen.sh && component_unpack "redis"script is used for unpacking the Redis files and changing the permissions as stated in the
At this point, everything has been executed as
root user at build time of the container. But the last highlighted line indicates that the default user must be changed from
USER 1001: this is a
non-rootuser UID, and here it is assigned to the image in order to run the current container as an unprivileged user. By doing so, the added security and other restrictions mentioned above are applied to the container.
Basically, it has been introduced an environment variable to set the file permissions and specify a user, in order to avoid running the container as root in its Dockerfile. That way, any time you run the container, it will already have the "instructions" to run as non-root user.
This is only one of the many ways to secure your containers. I encourage you to research other ways to turn your Docker images into
non-root containers, or to take advantage of the ready-to-run non-root containers already available from Bitnami.
If you want to learn more about non-root containers and Docker and Kubernetes security, check out the following articles: