How to Run Docker Daemon as a Non-Root User: Enhancing Security and Reducing Risk

Running the Docker daemon as a non-root user is a key security measure to minimize system risks. This post provides a detailed guide on why it's important, how to configure Docker for non-root operation using Rootless Mode, and how to troubleshoot common issues.

How to Run Docker Daemon as a Non-Root User: Enhancing Security and Reducing Risk

Introduction

Docker has revolutionized the way we build, ship, and run applications. However, by default, Docker requires root privileges, which can present security risks. If a malicious process or compromised container gains access to the Docker daemon running as root, it can potentially gain control over the host system.

Running Docker as a non-root user or in Rootless Mode significantly reduces this risk by isolating privileges and following the principle of least privilege. In this guide, we will:

  1. Discuss why running Docker as a non-root user is critical.
  2. Provide step-by-step instructions for enabling Docker daemon as non-root.
  3. Explain Rootless Mode for Docker with examples.
  4. Troubleshoot common issues you may encounter.
  5. Explore the limitations and trade-offs of Rootless Docker.

Why Run Docker as a Non-Root User?

1. Security Risks with Root-Level Docker

Docker, when run with root privileges, gives containers significant access to the host system. If an attacker gains control over the Docker daemon, they can execute arbitrary commands, escalate privileges, or compromise host files.

Common risks include:

  • Container escape vulnerabilities: A compromised container can break out to the host.
  • Malicious images: Downloading untrusted or compromised images might lead to security breaches.
  • Misconfigured Docker APIs: Exposing the Docker daemon API with root privileges can allow attackers to take over the host system.

2. Principle of Least Privilege

The best security practices dictate running services with the minimum level of privilege required. Docker should be no exception. By running Docker as a non-root user, you reduce the risk of privilege escalation and unauthorized system modifications.

Methods to Run Docker as a Non-Root User

By default, if you check dockerd (or containerd on some systems) process by running ps command like this:

ps -ef | grep docker | grep -v grep

you'll see that the main process of Docxker Deamin is running as root user:

root       13420       1  0 08:12 ?        00:00:04 /usr/bin/dockerd --containerd=/run/containerd/containerd.sock

Docker provides two main ways to run Docker processes without root:

  1. Add a user to the docker group – Allows you to run Docker commands without sudo.
  2. Rootless Mode – Runs the entire Docker daemon and CLI as a non-root user.

Option 1: Add a Non-Root User to the Docker Group

This method is simpler and works well for development and testing environments.

Step 1: Install Docker

If Docker is not already installed, install it:

sudo apt update
sudo apt install -y docker.io

If you're new to Docker or need help getting it set up, check out my detailed guide on Installing Docker on Different Platforms (Linux, Mac, Windows) to ensure you have Docker properly installed and ready to go.

Step 2: Add Your User to the Docker Group

By default, Docker creates a group called docker. Users in this group can run Docker commands without sudo. To add your user to the group:

sudo usermod -aG docker $USER
  • Replace $USER with the current username.
  • If you are adding a different user, use their specific username instead.

Step 3: Apply the Group Changes

Log out and log back in to apply the changes to your session. Alternatively, you can run:

newgrp docker

Step 4: Verify Non-Root Docker Operation

Run a test container without sudo:

docker run hello-world

If successful, you should see the "Hello from Docker!" message without requiring elevated privileges.

Option 2: Running Docker Daemon in Rootless Mode

For environments requiring stricter security, Docker introduced Rootless Mode. In this mode, both the Docker daemon (dockerd) and CLI run as a non-root user. This provides an additional layer of isolation and security.

Step 1: Install Dependencies

Rootless Mode requires a few additional tools. Install them with:

sudo apt update
sudo apt install -y uidmap dbus-user-session

Step 2: Configure Rootless Docker

You must install newuidmap and newgidmap on the host. 

Install Docker Rootless Toolkit:

sudo apt-get install docker-ce-rootless-extras

Create and install the currently logged-in user's AppArmor profile:

filename=$(echo $HOME/bin/rootlesskit | sed -e s@^/@@ -e s@/@.@g)
cat <<EOF > ~/${filename}
abi <abi/4.0>,
include <tunables/global>

"$HOME/bin/rootlesskit" flags=(unconfined) {
  userns,

  include if exists <local/${filename}>
}
EOF
sudo mv ~/${filename} /etc/apparmor.d/${filename}

Restart AppArmor

systemctl restart apparmor.service

Stop and disable "old" Docker service:

sudo systemctl disable --now docker.service docker.socket
sudo rm /var/run/docker.sock

Run the Rootless setup tool:

dockerd-rootless-setuptool.sh install

During installation, the tool automatically configures the necessary environment variables.

Step 3: Add Docker Rootless Paths to Shell

To use Docker commands, add the Docker binary path and socket to your shell environment:

export PATH=/home/$USER/bin:$PATH
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock

To make these changes persistent, add them to your shell configuration file (e.g., .bashrc, .zshrc):

echo 'export PATH=/home/$USER/bin:$PATH' >> ~/.bashrc
echo 'export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock' >> ~/.bashrc
source ~/.bashrc

Step 4: Verify Rootless Mode

Check the Docker configuration:

docker info

Look for rootless in the output to confirm that Docker is running in Rootless Mode.

Troubleshooting Common Issues

1. Permission Denied When Running Docker

If you see this error after adding your user to the docker group:

  • Ensure you’ve logged out and back in to apply group changes.

Confirm your user is in the docker group:

groups $USER

2. Missing dockerd-rootless-setuptool.sh

If the Rootless setup tool is missing, ensure Docker version 19.03 or later is installed. Update Docker if necessary:

sudo apt install -y docker-ce-rootless-extras

3. Ports Below 1024 Don't Work in Rootless Mode

By design, Rootless Docker cannot bind to ports below 1024 (e.g., HTTP on port 80). Use ports above 1024 or configure a reverse proxy like NGINX to forward requests.

Performance and Limitations

  • Performance: Rootless Docker may have slightly reduced performance due to user namespace overhead.
  • Storage Drivers: Certain drivers, like overlayfs have limited compatibility in Rootless Mode.
  • Networking: Rootless Docker relies on slirp4netns for networking, which may not match the performance of native Docker networking.

Conclusion

Running Docker as a non-root user is a critical step toward improving security, especially in production or sensitive environments. Whether you choose to add your user to the docker group for simplicity or configure Rootless Mode for enhanced isolation, both methods reduce the risks associated with root-level access.

  • Use the docker group for development environments where simplicity matters.
  • Opt for Rootless Mode in production, sensitive systems, or shared environments to maximize security.

By following this guide, you can minimize Docker's attack surface while maintaining its powerful containerization capabilities.

Read next

Understanding Docker Bench for Security Scores

Docker Bench for Security provides a comprehensive audit of your Docker environment, comparing it against CIS benchmarks to highlight potential security risks. At the end of the scan, a score is generated, reflecting how well your setup adheres to best practices.

Troubleshooting Docker Networking Problems

Docker networking is a crucial aspect of containerization, enabling communication between containers and between containers and external services. However, like any complex system, Docker networking can encounter issues that may disrupt application functionality and deployment.

Diagnosing Container Startup Failures

Containerization has revolutionized the way we develop, deploy, and manage applications. Docker containers provide an isolated environment that allows applications to run consistently across various systems. However, container startup failures.