Running containers as root has been the default for years, but it exposes your host to significant security risks. A compromised container running as root can escape to the host, modify system files, and take over the entire machine. Rootless container runtimes solve this by running the entire container stack under an unprivileged user account, eliminating the most dangerous class of container escape vulnerabilities.

This guide compares the three leading approaches to rootless containers in 2026: Docker Rootless Mode, Podman (designed rootless from day one), and containerd with rootless support. We’ll cover architecture, setup, security trade-offs, and production deployment patterns.

Rootless Containers: Why They Matter

Traditional container runtimes require root privileges to create namespaces, set up network bridges, and mount filesystems inside the container. When a container runs as root:

  • Namespace escapes become more likely — a kernel vulnerability in namespace isolation can grant full host access
  • Filesystem writes from inside the container map to root-owned files on the host
  • Network manipulation (iptables, routing tables) requires elevated privileges
  • Device access (GPUs, USB, serial ports) requires root-level device node permissions

Rootless containers use user namespaces (specifically userns-remap or rootlesskit) to map the container’s “root” user to an unprivileged UID on the host (typically UID 1000+). Even if an attacker escapes the container, they land as an unprivileged user with minimal host access.

The trade-offs are real: rootless containers cannot bind to ports below 1024, cannot use certain filesystems, and may have limited access to host devices. For most web services, APIs, and data processing workloads, these limitations are manageable.

Rootless Docker (Moby Engine)

Docker added official rootless mode in v20.10 and has steadily improved it. The Moby Project (github.com/moby/moby) is the upstream open-source engine behind Docker CE, with 71,532 stars and active development as of May 2026.

Architecture

Rootless Docker uses rootlesskit as the network and filesystem driver. Rootlesskit creates a user namespace, sets up a slirp4netns-based network stack (no root-level iptables needed), and handles UID/GID mapping automatically. The Docker daemon (dockerd) runs inside this namespace as an unprivileged user.

Installation and Setup

On most Linux distributions, rootless Docker is a single-command setup:

1
2
3
4
5
6
7
8
9
# Install Docker if not already present
curl -fsSL https://get.docker.com | sh

# Switch to rootless mode (creates a new systemd user service)
dockerd-rootless-setuptool.sh install

# Verify rootless mode is active
docker info --format '{{.SecurityOptions}}'
# Should include: name=rootless

Docker Compose Example (Rootless)

Create a rootless-compatible compose.yml for a typical web application stack:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
services:
  webapp:
    image: nginx:alpine
    ports:
      - "8080:80"  # Cannot use port 80 — must be > 1024
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    restart: unless-stopped

  app:
    image: myapp:latest
    ports:
      - "8081:3000"
    environment:
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis
    restart: unless-stopped

volumes:
  redis-data:

Rootless Docker with Reverse Proxy

Since rootless Docker cannot bind to ports 80/443, pair it with a system-level reverse proxy:

1
2
3
4
# /etc/caddy/Caddyfile — system-level Caddy (runs as root, binds to 80/443)
example.com {
    reverse_proxy localhost:8080
}

Then start the proxy with systemd and let rootless Docker handle the upstream services.

Limitations

LimitationImpactWorkaround
Cannot bind ports < 1024No direct HTTP/HTTPS/DNSUse reverse proxy or setcap
No --privileged flagLimited device accessUse --device with cgroup v2
Overlay2 storage driver issuesPerformance on some filesystemsUse fuse-overlayfs or vfs
No sysctl modificationsKernel parameter tuning blockedConfigure sysctl at host level
Limited ulimit changesNo custom resource limitsSet limits via systemd user unit

Podman — Rootless by Design

Podman (github.com/containers/podman) was built from the ground up to run rootless. With 31,638 stars and daily commits, it’s the most actively developed rootless-first container runtime.

Architecture

Podman uses a daemonless architecture — there is no central dockerd process. Each podman run command spawns containers directly as child processes of the invoking user. This means:

  • No daemon to compromise
  • No root-level process managing all containers
  • Native systemd integration (containers can be managed as systemd user services)
  • Built-in rootless support — no separate “rootless mode” to enable

Installation and Setup

1
2
3
4
5
6
7
8
9
# Ubuntu/Debian
sudo apt install podman

# RHEL/Fedora/CentOS
sudo dnf install podman

# Verify rootless (default)
podman info | grep -A5 security
# Should show: rootless: true

Podman Compose Example

Podman supports Docker Compose files natively via podman-compose:

1
2
3
4
5
# Install podman-compose
sudo apt install podman-compose

# Use the same compose.yml as above
podman-compose up -d

Or use Podman’s native Kubernetes YAML support:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# webapp-pod.yaml — Podman native pod definition
apiVersion: v1
kind: Pod
metadata:
  name: webapp-pod
spec:
  containers:
    - name: webapp
      image: docker.io/library/nginx:alpine
      ports:
        - containerPort: 80
          hostPort: 8080
      volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
          readOnly: true
    - name: redis
      image: docker.io/library/redis:7-alpine
      volumeMounts:
        - name: redis-data
          mountPath: /data
  volumes:
    - name: html
      hostPath:
        path: ./html
    - name: redis-data
      hostPath:
        path: ./redis-data
1
podman play kube webapp-pod.yaml

Podman Systemd Integration

One of Podman’s strongest features is native systemd integration:

1
2
3
4
5
6
7
# Generate a systemd unit file for a container
podman generate systemd --new --name webapp --files
# Outputs: container-webapp.service

# Enable and start as user service
systemctl --user enable container-webapp.service
systemctl --user start container-webapp.service

This means containers survive reboots and are managed by the same tooling as any other system service — no Docker daemon needed.

Podman Socket for Docker API Compatibility

If your tooling expects the Docker API socket:

1
2
3
4
5
6
7
8
# Start podman socket (rootless)
systemctl --user start podman.socket

# Point docker CLI at podman
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock

# docker-compose now works with podman backend
docker-compose up -d

Limitations

LimitationImpactWorkaround
No native docker buildDifferent build toolUse podman build or buildah
Compose support via 3rd partypodman-compose is communityUse podman play kube for native
GPU support requires extra setupCUDA/ROCm needs configUse --device nvidia.com/gpu=all
Some images require rootSetuid binaries breakUse rootful Podman or rootless-compatible images

containerd with Rootless Support

containerd (github.com/containerd/containerd) is the industry-standard container runtime, powering Kubernetes and Docker’s backend. With 20,694 stars, it added rootless support through the rootless containerd project.

Architecture

Rootless containerd uses the same rootlesskit infrastructure as rootless Docker, but without the Docker daemon layer. The containerd daemon (containerd) runs inside a user namespace, and ctr (containerd’s CLI) or nerdctl (Docker-compatible CLI) manages containers.

nerdctl is the recommended CLI — it provides a Docker-compatible interface on top of containerd:

1
2
3
4
5
# Install nerdctl + rootless containerd
curl -fsSL https://get.docker.com/rootless | sh

# Verify
nerdctl info | grep -i rootless

Setup and Configuration

1
2
3
4
5
6
7
8
# Install containerd + nerdctl (rootless)
curl -fsSL https://raw.githubusercontent.com/containerd/nerdctl/refs/heads/main/extras/rootless/containerd-rootless.sh | sh

# Start containerd (user service)
systemctl --user start containerd

# Verify
nerdctl run --rm hello-world

Nerdctl Compose Example

nerdctl includes native Docker Compose support (no separate tool needed):

1
2
# nerdctl-compose is built into nerdctl
nerdctl compose up -d
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# compose.yml — same format, works with nerdctl
services:
  nginx:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true  # Extra security layer

Kubernetes Integration

Since containerd is the default Kubernetes runtime, rootless containerd can serve as a development/test node:

1
2
3
4
5
6
# Run a rootless Kubernetes-like environment with k3d
k3d cluster create rootless-test --agents 1

# Or use nerdctl with containerd's CNI plugins
nerdctl network create mynet
nerdctl run --net mynet --name app myapp:latest

Limitations

LimitationImpactWorkaround
Steeper learning curvectr and nerdctl differ from dockerUse nerdctl for Docker-compatible CLI
Fewer high-level featuresNo docker stack, docker swarmUse Kubernetes or Docker Swarm separately
Rootless networking complexityslirp4netns performance overheadUse --net host where security allows
Less documentationRootless containerd is newerFollow rootless Docker docs (same base tech)

Comparison: Rootless Container Runtimes in 2026

FeatureRootless DockerPodmancontainerd (nerdctl)
GitHub Stars71,53231,63820,694
Last UpdatedMay 2026May 2026May 2026
ArchitectureRootlesskit + dockerdDaemonless, directRootlesskit + containerd
Rootless DefaultNo (opt-in)Yes (always)No (opt-in)
Docker ComposeNativepodman-composenerdctl compose (native)
Docker APINative (rootless)Via podman.socketNot available
Systemd IntegrationLimitedExcellent (native)Via systemd user units
Kubernetes RuntimeNo (CRI not supported)Via CRI-O bridgeYes (default CRI)
GPU SupportPartialPartialPartial
Build Tooldocker buildbuildah/podman buildbuildctl
User Namespacerootlesskitbuilt-inrootlesskit
Network Stackslirp4netnsslirp4netnsslirp4netns
Storage Driversfuse-overlayfs, vfsfuse-overlayfs, vfsoverlayfs, fuse-overlayfs
Best ForDocker ecosystem usersRootless-first, systemdKubernetes, production infra

Choosing the Right Rootless Runtime

Use Rootless Docker if: You have existing Docker Compose files, Docker-based CI/CD pipelines, or tooling that requires the Docker API socket. It’s the smoothest migration path from rootful Docker.

Use Podman if: You want rootless by default with no configuration, need systemd integration for production deployments, or prefer a daemonless architecture. Podman is the safest choice for new deployments where Docker API compatibility isn’t required.

Use containerd/nerdctl if: You’re building Kubernetes infrastructure, need the CRI (Container Runtime Interface), or want the most production-proven container runtime with rootless capability added on top.

Security Best Practices for Rootless Containers

  1. Enable seccomp profiles — All three runtimes support seccomp filtering. Use the default profile or create custom ones that block unnecessary syscalls.
  2. Drop all capabilities — Add --cap-drop ALL and only add back specific capabilities your container needs.
  3. Use read-only root filesystems — Mount volumes explicitly for writable paths only.
  4. Set resource limits — Use --memory, --cpus, and --pids-limit to prevent resource exhaustion.
  5. Keep the host kernel updated — User namespace security depends on kernel patches. Use a supported kernel (5.10+ recommended).
  6. Use AppArmor or SELinux — These mandatory access control systems add a second layer beyond user namespaces.

For related container security hardening, see our Docker Bench vs Trivy vs Checkov guide and container sandboxing comparison. For container registry security, check our registry proxy cache guide.

Why Self-Host Your Containers Rootless?

Running containers in rootless mode isn’t just about security — it’s about operational resilience and multi-tenancy. When you self-host containerized services, rootless runtimes provide several advantages that directly impact your infrastructure reliability and team productivity.

Data Ownership and Isolation: When containers run as unprivileged users, the damage from a compromised workload is inherently bounded. A breached web application container cannot read /etc/shadow, modify /etc/passwd, or install system-level rootkits. This isolation model is particularly valuable when hosting third-party containers from public registries where you cannot verify the contents of every layer.

Cost Savings Through Multi-Tenancy: Rootless containers enable safe multi-tenant hosting on shared infrastructure. Different teams or projects can run their containers under separate user accounts on the same host, without any single container gaining root access to shared resources. This eliminates the need for separate VMs per team, reducing infrastructure costs significantly.

No Vendor Lock-In: By adopting rootless container runtimes, you avoid dependency on cloud-managed container services that charge premiums for managed orchestration. The same container images and compose files work identically on bare metal, VMs, or any cloud provider. Rootless mode ensures your deployment model is portable and self-contained.

Regulatory Compliance: Many compliance frameworks (SOC 2, ISO 27001, HIPAA) require principle of least privilege for workload execution. Rootless containers satisfy this requirement natively — the container process runs with the minimum permissions needed, and any escalation requires a separate kernel-level exploit rather than a simple misconfiguration.

Simplified Auditing: With rootless containers, the UID mapping between container and host is explicit and auditable. You can trace any file modification or network activity back to a specific unprivileged user account, making forensic analysis significantly more straightforward than with root-level containers where all activity appears as root.

FAQ

What is the difference between rootless Docker and rootless Podman?

Rootless Docker uses rootlesskit to run the Docker daemon inside a user namespace. Podman was designed rootless from the start and has no daemon — each container runs as a direct child process of the user. Podman also has better systemd integration and doesn’t require a separate “rootless mode” setup.

Can rootless containers access the host network?

Rootless containers use slirp4netns for networking, which provides NAT-based connectivity. They can reach the host via the gateway IP (typically 10.0.2.2) but cannot directly bind to host interfaces. For full host network access, use --net host with Podman or nerdctl, though this reduces isolation.

Are rootless containers slower than rootful containers?

There is a minor performance overhead from slirp4netns networking (typically 5-15% network throughput reduction) and fuse-overlayfs storage (slightly higher latency for filesystem operations). For most workloads — web servers, APIs, databases, batch processing — this overhead is negligible.

Can I run Kubernetes with rootless containers?

Yes, but with limitations. Rootless containerd (via nerdctl) can serve as a development node. For production Kubernetes, consider using rootful containerd (the default) with Pod Security Standards and seccomp profiles instead. Rootless Kubernetes is an active area of research but not production-ready.

Do rootless containers support Docker Compose?

Rootless Docker supports docker compose natively. Podman requires podman-compose (community) or podman play kube (native Kubernetes YAML). containerd/nerdctl includes built-in compose support via nerdctl compose. All three approaches handle the same compose.yml format.

Which rootless runtime should I choose for production?

For production server deployments, containerd (with nerdctl) is the most battle-tested choice — it powers the majority of Kubernetes clusters worldwide. For developer workstations and small-scale self-hosting, Podman offers the best user experience with its daemonless design and systemd integration.