Podman and Rootless Containers
Podman runs containers without a privileged background daemon, and without root by default - a command-compatible alternative to Docker built specifically around closing the security gap its daemon model leaves open.
Docker Basics covers
Docker's model: every command talks to dockerd, a root-owned daemon.
Podman takes a different architectural approach to the same problem -
running containers - built around two changes: no daemon, and no root
requirement.
No daemon
Docker's dockerd runs continuously in the background, owns every
container's process tree, and everything routes through it. Podman has
no equivalent background service: each podman run forks and manages
the container process directly, as a normal child process of whatever
invoked it. One practical consequence: there's no single daemon that,
if it crashes or is restarted, takes every running container's
management connection down with it.
Command compatibility
Podman deliberately mirrors Docker's command-line interface closely enough that this often just works:
alias docker=podman
podman pull nginx:1.27
podman run -d -p 8080:80 nginx
podman ps
podman build -t myapp:1.0 .
podman exec -it <container-id> bash
Dockerfiles, docker-compose.yml files (via podman-compose or
Podman's own Compose support), and muscle memory from Docker mostly
transfer directly - the commands in
Docker Basics work
close to unmodified with podman substituted for docker.
Rootless by default
This is the actual point of Podman, more than the missing daemon.
Running podman run as a normal, unprivileged user starts the
container without root anywhere in the picture - Podman uses user
namespaces to map the container's internal root user to an unprivileged
UID on the host, so a process that's root inside the container has
no elevated privileges outside it at all.
podman run --rm -it alpine id
uid=0(root) gid=0(root) groups=0(root)
Inside the container, that's root. On the host, the actual process runs as the unprivileged user who launched it - so a container escape or a compromised image doesn't hand an attacker root on the host the way it potentially could with a root-owned Docker daemon in the loop. Docker supports a rootless mode too, but it's opt-in and less commonly deployed in practice; with Podman, rootless is simply the default way of running it.
Pods
Podman's name comes from "Pod Manager" - it can group several
containers into a pod that shares a network namespace (and
therefore localhost), the same grouping concept Kubernetes pods use:
podman pod create --name mypod -p 8080:80
podman run -d --pod mypod nginx
podman run -d --pod mypod redis
Containers in the same pod reach each other over localhost, without
needing a container-to-container network link the way separate Docker
containers would.
Running containers as systemd services
Because Podman doesn't need a background daemon of its own, containers integrate cleanly with systemd (see systemd and Services) as ordinary units - the standard way to make a Podman container start at boot and restart on failure like any other service:
podman generate systemd --new --files --name mycontainer
Generates a .service unit file for an existing container, ready to
drop into /etc/systemd/system/ and enable normally. This command
still works but is now considered legacy - the Podman project's current
recommendation is Quadlet: a .container (or .pod) unit file,
written directly rather than generated, that a systemd generator turns
into a real service automatically. Reach for Quadlet on a current
Podman install; generate systemd remains useful mainly for a quick
one-off or on an older version without Quadlet support.
When to reach for which
Docker remains the more common default in tutorials, CI systems, and existing tooling, and its Compose/Swarm ecosystem is more mature. Podman is the stronger choice specifically where the root-daemon model is a concern - multi-user machines, security-sensitive environments, or anywhere "no background daemon and no root by default" outweighs Docker's larger ecosystem.