Rootless Docker runs containers as an unprivileged user, meaning the container processes don’t have elevated privileges on the host system. This is a significant security win because if a container is compromised, the attacker’s access is limited to the user’s permissions, not the entire host.
Let’s see rootless Docker in action. First, ensure you have Docker installed. Then, you’ll need to set up user namespaces.
sudo apt update
sudo apt install -y dbus-user-session
Next, configure sysctl to allow user namespace creation. This usually involves adding or uncommenting lines in /etc/sysctl.d/ files. A common place is 99-sysctl.conf.
echo 'kernel.unprivileged_userns_clone = 1' | sudo tee -a /etc/sysctl.d/99-sysctl.conf
sudo sysctl --system
Now, we can set up the rootless Docker environment for a specific user. Replace your_username with the actual username.
sudo usermod --add-to-group dockremap your_username
sudo mkdir -p /etc/docker/rootless
sudo tee /etc/docker/rootless/daemon.json > /dev/null <<EOF
{
"data-root": "/home/your_username/.local/share/docker"
}
EOF
The dockremap group is crucial. It allows the rootlesskit to remap user IDs within the container to a range of UIDs that are unprivileged on the host. The data-root configuration tells Docker where to store its data, keeping it within the user’s home directory.
After these setup steps, the user can start the rootless Docker daemon.
export PATH="$HOME/.local/bin:$PATH"
export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock"
systemctl --user enable docker
systemctl --user start docker
Now, you can run Docker commands as this unprivileged user. Notice that the DOCKER_HOST environment variable points to the user’s socket.
docker run hello-world
This hello-world container will run without requiring sudo and its processes will execute as the unprivileged user who started the daemon. The rootlesskit component, which is part of the rootless Docker installation, is responsible for creating and managing these user namespaces, effectively isolating the container’s root user from the host’s root user.
The magic of rootless Docker lies in user namespaces. When a container starts, the UIDs and GIDs inside the container are mapped to a range of unprivileged UIDs and GIDs on the host. This means that even though the container’s root user sees itself as UID 0, on the host, it’s actually a different, unprivileged UID. This isolation is managed by rootlesskit, which acts as the parent process for the Docker daemon when running in rootless mode. It intercepts calls to clone() and unshare() to create these namespaces.
A common pitfall is forgetting to restart the user’s session or log out and back in after adding the user to the dockremap group, or not setting the DOCKER_HOST environment variable correctly. Without the correct DOCKER_HOST, docker commands will attempt to connect to the system-wide rootful Docker daemon, not the user’s rootless one.
The next hurdle you’ll likely encounter is understanding how volume mounts work in rootless mode, particularly concerning permissions and the user namespace remapping.