BlogLinux & scripting

Rootless Docker and why containers shouldn't run as root

Run the Docker daemon and your containers as a non-root user so a container escape lands unprivileged, plus the subuid, cgroups, and storage gotchas.

Oct 7, 2025·4 min readIntermediate·By the SecOpsLog team · command-tested

Default Docker runs the daemon as root. A container escape or daemon bug often yields uid 0 on the host — game over. Rootless Docker runs dockerd under your user account, maps container uids through subordinate id ranges (/etc/subuid, /etc/subgid), and uses slirp4netns or pasta for networking without touching host iptables as root. The tradeoff is friction: some flags, storage drivers, and cgroup versions behave differently than rootful Docker.

This note installs rootless Docker, verifies subuid mappings, runs a sample container, and documents the limitations you hit in CI and on older kernels. Pair with Docker hardening for seccomp, read-only rootfs, and capability drops; Linux essentials for user namespaces fundamentals.

Rootless Docker setup and verification

Install script creates ~/.config/systemd/user/docker.service. Logout/login required so subuid maps apply. Test before migrating prod workloads.

1Installprerequisitesuidmap, slirp4netns/fuse-overla…2dockerd-rootless-setuptoolinstall as normal user3Verifysubuid/subgid65536 ids for user4systemctl --userstart dockeruser systemd unit5docker runhello-worldconfirm unprivileged6Check root incontainerid shows mapped uid7Document limitshost networking, volumes

Install rootless Docker

Use the official rootless install script — it configures XDG_RUNTIME_DIR, user systemd, and socket at $XDG_RUNTIME_DIR/docker.sock. Export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock in your shell profile so CLI talks to the user daemon, not /var/run/docker.sock.

Rootless mode uses fuse-overlayfs or btrfs when the kernel denies unprivileged overlay mounts. On RHEL and Ubuntu LTS, package names differ but the flow is the same: prerequisites, install script, user systemd enable. Document docker context usage if developers switch between rootful Colima and rootless Linux workstations.

install-rootless.sh
curl -fsSL https://get.docker.com/rootless | sh
# Add to ~/.bashrc
export DOCKER_HOST=unix://${XDG_RUNTIME_DIR}/docker.sock
export PATH=/usr/bin:$HOME/bin:$PATH
systemctl --user enable --now docker

Subordinate uid/gid maps

Rootless mode maps container root (uid 0 inside) to a high unprivileged uid on the host — typically the first entry in /etc/subuid. Without 65536 subids per user, nested namespaces fail mysteriously. Corporate LDAP users need subuid entries provisioned at account creation.

Slirp4netns provides user-mode networking without root iptables rules — fine for dev, sometimes limiting for published ports at scale. Pasta (passt) improves performance on newer kernels. For production orchestration, Kubernetes with user namespaces (1.30+) pursues similar goals at pod level; rootless Docker is the laptop and CI builder story.

/etc/subuid
# user: start: count
alice:100000:65536
# container uid 0 → host uid 100000
bash — verify rootless contextlive
docker info | grep rootless
rootless: true
docker run --rm alpine id
uid=0(root) gid=0(root) # inside container
ps aux | grep runc | head -1
host process runs as alice, not root
Rootless is not rootless Kubernetes
Rootless Docker protects the host from container uid 0 — it does not replace pod security standards, network policies, or secrets management. Some features break: `--net=host`, bind mounts to root-only paths, and certain volume drivers. Read the rootless known limitations doc before moving stateful databases.
Rootful vs rootless Docker
Rootless wins
Dev laptops and CI agents
Multi-tenant build hosts
Escape lands as user alice
No setuid docker binary
Rootful still needed
Host network plugins
Legacy --privileged workloads
Certain NFS/CIFS mounts
Some GPU passthrough setups

Where this goes next

Combine rootless mode with cap_drop: ALL, read-only rootfs, and non-root USER in Dockerfiles. On orchestrators, migrate the same principles to Kubernetes Pod Security. Docker hardening covers seccomp profiles and image minimalism; Linux hardening covers the host OS beneath the daemon.

CI builders benefit most from rootless — compromised build scripts lose root on the host. Production Kubernetes nodes still run containerd as root; rootless Docker is not a substitute for pod security policies there.

Go deeper in a courseDocker hardeningRootless mode, seccomp, capabilities, and minimal production images.View course

Related posts