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:
- Discuss why running Docker as a non-root user is critical.
- Provide step-by-step instructions for enabling Docker daemon as non-root.
- Explain Rootless Mode for Docker with examples.
- Troubleshoot common issues you may encounter.
- 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.sockDocker provides two main ways to run Docker processes without root:
- Add a user to the
dockergroup – Allows you to run Docker commands withoutsudo. - 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
$USERwith 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-extrasCreate 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.serviceStop and disable "old" Docker service:
sudo systemctl disable --now docker.service docker.socket
sudo rm /var/run/docker.sockRun 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
overlayfshave limited compatibility in Rootless Mode. - Networking: Rootless Docker relies on
slirp4netnsfor 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
dockergroup 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.