Running without privileges has costs, and some of them fail quietly. This listing, run as l3rootless, asks for an I/O limit, starts a container on privileged port 81, then a small web server on port 33081:
docker run --rm --device-write-bps /dev/sdd:1mb alpine:3 true
docker run -d --name l3-rl-81 -p 81:8080 alpine:3 sleep 600 >/dev/null
R='HTTP/1.1 200 OK\r\nContent-Length: 15\r\n\r\nrootless hello\n'
docker run -d --name l3-rl-web -p 33081:8080 -e R="$R" alpine:3 sh -c >/dev/null \
'while :; do printf "$R" | nc -l -p 8080; done'
sleep 5; curl -s -m 3 http://localhost:33081/ || echo "33081 fails: curl exit $?"
journalctl --user -u docker.service --since "1 min ago" -o cat | grep -m1 'TCP port \*/81'
docker rm -f l3-rl-81 >/dev/null; sleep 5; curl -s -m 3 http://localhost:33081/WARNING: Your kernel does not support BPS Block I/O write limit or the cgroup is not mounted. Block I/O BPS write limit discarded. 33081 fails: curl exit 7 Listen failed for HOST TCP port */81: Permission denied rootless hello
The limitations, as measured here and as Docker 514 's rootless documentation lists them:
Privileged ports. An ordinary user cannot bind ports below 1024. docker run -p 81:8080 reported success, but pasta could not listen, and while that request stood, pasta also refused to open newly published ports, 33081 included, until the offending container was removed. Fix it with net.ipv4.ip_unprivileged_port_start=0 in /etc/sysctl.conf, or setcap cap_net_bind_service=ep on rootlesskit, or publish above 1024 behind a reverse proxy.
Resource limits. Only controllers systemd 142,543 delegates to the user work: here cpu, memory and pids, so --memory and --cpus worked but the I/O limit was discarded. A drop-in for user@.service delegates the rest.
Networking. Traffic passes through a slower user-mode stack; container IPs are not reachable from the host; --network host means RootlessKit 1,304 's namespace; overlay networks, and so Swarm 514 , are unsupported.
Other gaps. No AppArmor 454,622 , checkpoint and restore, SCTP ports or NFS data root; ping needs net.ipv4.ping_group_range to include your group (it did here).
A workstation or CI runner that builds images rarely hits these, and a stack like BookNest's stays within them.