coldwa.st
All guidesProgrammingWebDataToolsDatabasesHaskellConceptsCabal & buildsToolchainCompilerPerformanceEditor & HLS

Programming · DevOps · Containers

Docker vs Podman: which container engine, and when?

By ColdwastUpdated Jun 27, 20269 min read#docker#podman#containers
A 3D render of three identical black server units side by side with green status lights
Docker and Podman both run the same OCI-format containers — three identical server units pictured here. The real differences are in how each tool starts and manages those containers, not in the containers themselves.

Quick answer: Docker and Podman do the same core job — build and run containers — and they use the same image format, so an image built with one runs on the other. The main difference is architecture: Docker runs containers through a long-running central daemon (dockerd) that typically runs as root, while Podman is daemonless and rootless by design, launching each container as a normal child process. Their command lines are close enough that alias docker=podman covers most everyday use. Pick Podman when you want no root daemon and tight systemd integration; stick with Docker when you rely on Docker Desktop, a mature Compose workflow, or its larger ecosystem.

If you are new to either tool, it helps to first understand what Docker and containers are. This guide assumes that and focuses on how the two engines differ.

Architecture: daemon vs daemonless

Docker uses a client-server model. The docker command you type is a client that talks to a background service, the Docker daemon (dockerd), which actually creates and runs your containers. That daemon is long-running and, in the default setup, runs as root. It is convenient — one service manages everything — but it is also a single privileged process that owns every container on the host.

Podman takes a different path. There is no central daemon: when you run a container, Podman forks and execs it directly as a child process of your shell, using the same underlying Linux primitives (namespaces, cgroups). Each container is just a normal process tree. This daemonless model means there is no always-on root service to compromise, and a crash in one container does not pass through a shared daemon.

Rootless containers and security

The architecture difference leads to the security difference people care about most. Podman was built to run rootless — an unprivileged user can build and run containers without root, using user namespaces to map container UIDs to the host. Docker can also run rootless, and has supported it for years, but its default install still centres on the root daemon, so rootless is an opt-in mode rather than the baseline.

Not having a root daemon reduces the attack surface: there is no privileged background service that a container escape could target to take over the host. For multi-user servers and CI runners, that "no root daemon" property is a genuine, concrete reason teams move to Podman. It is not magic — containers still need careful configuration — but the default posture is more conservative.

A large cargo ship loaded with stacked shipping containers at a port at night
The word "container" comes from shipping: standardised boxes that move the same way on any ship or crane. Software containers borrow the idea — and both Docker and Podman use the same OCI standard, so the boxes are interchangeable.

Same images, near-identical CLI

Here is the part that makes switching painless: both tools follow the OCI (Open Container Initiative) standards for images and runtimes. An image you build with Docker runs under Podman and vice versa, and both pull from the same registries (Docker Hub, GitHub Container Registry, Quay, and others). There is no Docker-only or Podman-only image format.

The command lines are deliberately close. podman run, podman build, podman ps and podman pull mirror their Docker equivalents, with the same common flags. Many people simply set an alias:

alias docker=podman

and keep their existing habits. Dockerfiles work as-is under Podman too. The CLI is not 100% identical in every corner case, but for day-to-day building and running it is close enough that muscle memory transfers.

Pods: Podman's Kubernetes-flavoured grouping

Podman is named after the pod — a concept it borrows from Kubernetes. A pod is a group of containers that share resources such as a network namespace, so they can talk to each other over localhost as if they were on the same machine. Podman can create and manage these pods directly, which makes local development feel closer to how things run in a Kubernetes cluster. Docker has no native "pod" primitive in the same sense; you compose multi-container setups with Compose networks instead.

systemd integration

Because Podman containers are ordinary child processes rather than children of a daemon, they slot naturally into systemd, Linux's service manager. Historically you could run podman generate systemd to produce a unit file for a container; the current, recommended approach is Quadlet, which lets you describe containers in declarative unit-style files that systemd manages directly — starting them on boot, restarting on failure, and tracking them like any other service. For servers that already use systemd to run everything else, this is a clean way to keep containers under the same supervisor without an extra daemon.

Compose: docker compose vs podman

Many projects rely on Compose to bring up several containers from one YAML file. Docker ships docker compose (the Compose v2 plugin) as a first-class, well-maintained tool. Podman supports Compose workflows too: it can work with the separate podman-compose tool, and Podman also provides a socket that the standard Compose tooling can talk to, so existing compose.yaml files often run with little or no change. In practice, Docker's Compose experience is the more mature and polished of the two, which is one reason teams with heavy Compose use sometimes stay on Docker.

Docker Desktop licensing vs Podman's open-source model

On Windows and macOS, Docker is usually used through Docker Desktop. Docker Desktop is free for personal use, education and small businesses, but it requires a paid subscription for larger organisations (above Docker's published employee/revenue threshold). That licensing change is a real budget and compliance consideration for bigger companies.

Podman is fully open source and free to use, with no per-seat licence. Its desktop companion, Podman Desktop, is likewise open source. For organisations that want to avoid commercial desktop licensing — or simply prefer an open-source stack end to end — that difference matters as much as any technical one.

So which should you use?

CriterionDockerPodman
ArchitectureCentral daemon (dockerd)Daemonless (fork/exec per container)
RootlessSupported, opt-inRootless by design (default)
Image formatOCIOCI — interchangeable with Docker
CLIReference CLINear-identical (alias docker=podman)
PodsNo native pod primitiveNative pods (Kubernetes-style)
systemdRuns under the daemonNative units via Quadlet
Composedocker compose (mature)podman-compose / Compose via socket
Desktop licensingDocker Desktop paid for large orgsOpen source, free (Podman Desktop)

There is no universal winner. Choose Podman when you want no root daemon, rootless containers as the default, native systemd/Quadlet management, or to avoid Docker Desktop licensing. Stick with Docker when you depend on Docker Desktop, a mature Compose workflow, or the breadth of its ecosystem and documentation. Because both speak OCI, you can also mix them — build with one, run with the other — or trial Podman without throwing away your existing images and Dockerfiles. If you later need to orchestrate many containers across machines, that is a job for Kubernetes, which sits above both.