Summary: Podman is the default runtime. Docker is opt-in behind containers_install_docker, and the docker group is only granted when Docker is actually installed.

Context

The Fedora machine ran both. Not because anything needed both — because container-tools bundled podman and docker together, and nobody had ever made the call. The cost was a second root daemon, a systemd socket, and a second container storage pool holding its own copy of overlapping image layers.

Details

What tipped it

Three things, in order of weight:

The docker group is root-equivalent. Anyone in it can start a container that bind-mounts / and writes as uid 0. Adding a user to docker unconditionally, as the old role did, is a privilege grant dressed as a convenience. Podman rootless needs no such group.

Two storage pools is two copies. On a machine that hit 84 % of 475 G, a duplicate image store is not a rounding error.

Nothing on the machine actually required the Docker socket. Worth re-checking rather than assuming — some tooling reaches for /var/run/docker.sock directly and will not accept a Podman socket without being told to.

How it’s expressed

containers_install_podman: true
containers_install_docker: false
containers_user_groups: [audio, video, render]

The docker group is appended to that list only when containers_install_docker is true:

groups: "{{ containers_user_groups + (['docker'] if containers_install_docker | bool else []) }}"

Lingering is enabled via loginctl enable-linger so rootless Podman units survive logout — the failure mode otherwise is a service that works while you are logged in and vanishes when you are not.

The honest counterargument

Podman’s Docker compatibility is good but not total. Compose files with unusual networking, tools that shell out to a docker binary, and anything expecting Docker’s specific socket semantics will need attention. If that becomes a running cost rather than a one-time fix, flipping the flag is one line and the reasoning above is not so strong that it should not be revisited.