Docs / Containers & Docker / Running Docker in Rootless Mode for Security

Running Docker in Rootless Mode for Security

By Admin · Mar 15, 2026 · Updated Apr 24, 2026 · 523 views · 2 min read

Rootless Docker runs the Docker daemon and containers without root privileges, significantly reducing the attack surface. If a container escape occurs, the attacker gains only unprivileged user access instead of root. This guide covers setting up rootless Docker on production systems.

Prerequisites

# Install required packages
sudo apt install uidmap dbus-user-session fuse-overlayfs slirp4netns

# Check subordinate UID/GID ranges exist for your user
grep $USER /etc/subuid /etc/subgid
# Should show: username:100000:65536

Installation

# If rootful Docker is installed, stop it first (not required to remove)
sudo systemctl disable --now docker docker.socket

# Install rootless Docker
dockerd-rootless-setuptool.sh install

# Or install from scratch
curl -fsSL https://get.docker.com/rootless | sh

# Add to shell profile
export PATH=$HOME/bin:$PATH
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock

Managing the Rootless Daemon

# Start/stop (uses systemd user services)
systemctl --user start docker
systemctl --user stop docker
systemctl --user enable docker

# Enable lingering (keeps service running after logout)
sudo loginctl enable-linger $USER

# Check daemon status
systemctl --user status docker
docker info | grep -i rootless

Networking Differences

# Rootless Docker uses slirp4netns for networking
# Port mapping works but binds to unprivileged ports (>1024) by default

# To use privileged ports (80, 443):
# Option 1: Use sysctl
sudo sysctl net.ipv4.ip_unprivileged_port_start=80

# Option 2: Use a reverse proxy (Nginx/Caddy) on the host

# Option 3: Use rootlesskit port driver
# ~/.config/docker/daemon.json
{
    "features": {
        "rootless": true
    }
}

Storage Configuration

# Rootless Docker stores data in ~/.local/share/docker
# Use overlay2 with fuse-overlayfs
# ~/.config/docker/daemon.json
{
    "storage-driver": "fuse-overlayfs"
}

# Or if kernel supports native overlayfs with user namespaces:
{
    "storage-driver": "overlay2"
}

Docker Compose with Rootless

# Docker Compose works normally with rootless Docker
# Ensure DOCKER_HOST is set
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock

docker compose up -d
docker compose ps

Limitations

  • Cannot use --privileged containers
  • Limited network performance (slirp4netns overhead)
  • Cannot bind to ports below 1024 without configuration
  • No support for --net=host
  • AppArmor/SELinux profiles may need adjustment

Best Practices

  • Use rootless Docker for all development environments and non-privileged workloads
  • Enable lingering so the daemon survives user logout
  • Use a reverse proxy for ports 80/443 instead of lowering unprivileged port start
  • Use overlay2 storage driver with kernel 5.13+ for best performance
  • Combine with user namespace remapping for defense in depth

Was this article helpful?