
Docker has been the default container tool since 2013. Almost every tutorial, CI/CD pipeline, and cloud platform was built around it.
Docker is still far ahead: in the Stack Overflow Developer Survey 2025, 71.1% of respondents used Docker and 11.1% used Podman. But Podman is now a real option rather than a curiosity, especially where rootless containers, Red Hat platforms or Docker Desktop licensing matter.
This post covers what actually separates the two tools, with real commands, real performance numbers, and real-world scenarios — so you can make the right call for your environment.
Why Are Teams Looking at Podman Now?
Three things happened that pushed teams to reconsider Docker:
1. Docker Desktop licensing changed. In 2022, Docker made Docker Desktop a paid product for companies with more than 250 employees or more than $10 million in revenue. For large teams on macOS or Windows, this translates to $50,000–$120,000 per year. Podman Desktop is completely free with no licensing restrictions.
2. Kubernetes removed Docker as a runtime. Kubernetes dropped dockershim support in version 1.24 (May 2022). Docker containers still work in Kubernetes — but through containerd, not Docker directly. This sent a clear signal that Docker is no longer the preferred runtime for Kubernetes.
3. Security teams started blocking Docker’s root daemon. The dockerd daemon runs as root. Adding a user to the docker group on Linux is functionally equivalent to giving them root access to the host. Security audits started flagging this. Podman’s rootless design fixed this problem cleanly.
What Is Docker?
Docker uses a client-server architecture. The Docker CLI sends commands to dockerd — a daemon that runs as a background service with root privileges. That daemon manages everything: containers, images, networks, and volumes.
You → docker CLI → dockerd (root daemon) → container processes
The daemon is always running, even when no containers are active, so it holds some memory and is one more privileged service to patch and monitor.
If dockerd crashes or is restarted without live-restore enabled, the containers it manages go down with it. That shared dependency is the main operational trade-off of a daemon-based design.
Docker Hub had a major outage in October 2025 when AWS US-East-1 went down. Teams that depended on Docker Hub for base images found their entire CI/CD pipelines broken — even for builds that should have used cached images, because dockerd was still making HEAD requests to the registry.
What Is Podman?
Podman stands for Pod Manager. It was developed by Red Hat and is the default container engine in Red Hat Enterprise Linux 8 and later.
Podman has no daemon. Each container runs as a direct child process of the user who started it.
You → podman CLI → container process (runs as your user)
No background service. No privileged socket. No single point of failure.
Podman has been production-ready since version 2.0 in 2020. The current release line is 6.x (6.1 as of September 2026), with 5.8 still receiving fixes. It is the default container tool on Red Hat Enterprise Linux, Fedora and CentOS Stream.
Architecture — The Core Difference
This is where everything else comes from.
Docker:
The dockerd daemon sits between you and your containers. All container operations go through it. If it fails, everything fails. Because it runs as root, a compromised daemon gives an attacker root access to the entire host.
Podman:
Each podman run command forks a container directly as a child process. There is no central service. If one container crashes, others keep running. The attack surface is dramatically smaller.
This architectural difference explains every other difference between the two tools.
CLI — The Commands Are Almost Identical
Podman was designed to be a drop-in replacement for Docker. Most commands are identical:
Run a container:
# Docker
docker run -d --name nginx -p 8080:80 nginx
# Podman
podman run -d --name nginx -p 8080:80 nginx
Build an image:
# Docker
docker build -t myapp:1.0 .
# Podman
podman build -t myapp:1.0 .
List containers:
docker ps
podman ps
View logs:
docker logs nginx
podman logs nginx
Execute a command inside a container:
docker exec -it nginx bash
podman exec -it nginx bash
Stop and remove:
docker stop nginx && docker rm nginx
podman stop nginx && podman rm nginx
Teams migrating from Docker to Podman typically set up an alias first:
alias docker=podman
This lets them test Podman without changing any existing scripts or muscle memory.
Security — Where Podman Has a Clear Advantage
Docker’s security model:
dockerddaemon runs as root- All users who run Docker commands need access to the Docker socket
- Being in the
dockergroup is functionally equivalent to having sudo access - If a container escapes, it potentially has root on the host
- Docker containers are launched with 14 kernel capabilities by default
Podman’s security model:
- Containers run as the user who launched them — no root required
- No shared socket — each user manages their own containers
- Rootless by default, not as an afterthought
- If a container escapes, the attacker only has the privileges of that user
- Podman containers are launched with 11 kernel capabilities by default
Real-world scenario:
You have a shared CI/CD server. Multiple developers need to run containers to test their builds.
With Docker, you add them all to the docker group. Now they all have effective root access to the server. One compromised account compromises the entire machine.
With Podman, each developer runs containers under their own user account. No group membership needed. No elevated privileges. A compromised account cannot affect other users or the host system.
# Podman — run a container as a regular user, no sudo
podman run -d --name test-app -p 3000:3000 myapp:latest
# Check who owns the process
ps aux | grep test-app
# Shows: youruser 12345 ... podman run ...
Performance — Real Numbers
Both tools produce identical container runtime performance because they use the same underlying OCI runtime. The differences are in overhead and resource usage.
Idle overhead: Docker keeps dockerd (and containerd) running even with no containers, so there is always some baseline memory in use. Podman has no daemon, so with no containers running it uses nothing. On a developer laptop the difference is small; on a small VM or edge device it can matter. Measure it on your own host with ps or systemctl status docker rather than trusting a generic number.
Container startup time:
In practice, container startup time is similar for both. Both hand off to an OCI runtime (runc or crun) to actually start the container, and image size, storage driver and network setup matter far more than daemon versus no daemon. Benchmark your own workload before switching for speed.
CI/CD pipeline impact:
Where Podman more reliably helps CI is by removing Docker-in-Docker: rootless Podman can build images without a privileged container or a mounted Docker socket, which simplifies the pipeline and removes a common security finding.
Concurrent containers:
Docker’s daemon becomes a bottleneck at high container counts. Podman handles 100+ concurrent containers with linear performance because there is no central service being hit by every operation.
One important caveat: Docker is marginally faster for individual container starts when the daemon is already warm. If you are running one or two containers at a time on a developer laptop, the difference is negligible.
Pods — A Feature Unique to Podman
Podman supports pods natively. A pod is a group of containers that share the same network namespace — exactly like a Kubernetes pod.
This is useful when developing applications that will run on Kubernetes. You can test your exact pod configuration locally before deploying to a cluster.
Create a pod with a web server and a database:
# Create the pod
podman pod create --name webapp --publish 8080:80
# Add containers to the pod
podman run --pod webapp -d --name web nginx
podman run --pod webapp -d --name db postgres:15
# List the pod
podman pod ps
# Stop the whole pod
podman pod stop webapp
Generate Kubernetes YAML directly from a running pod:
podman generate kube webapp > webapp-k8s.yaml
This YAML can be applied directly to a Kubernetes cluster without modification. Docker has no equivalent for this.
Deploy a Kubernetes manifest locally with Podman:
podman kube play webapp-k8s.yaml
This closes the gap between local development and Kubernetes production.
Systemd Integration
Podman integrates natively with systemd. You can manage containers as system services — they start on boot, restart on failure, and log to journald like any other service.
Generate a systemd service file for a container:
# Generate the service file
podman generate systemd --name webapp --files --new
# Enable it as a user service
systemctl --user enable container-webapp.service
systemctl --user start container-webapp.service
# Check status
systemctl --user status container-webapp.service
With Docker, running containers as systemd services requires writing custom unit files that call docker run. Podman does this automatically.
Docker Compose vs Podman Compose
Docker Compose is now built into the Docker CLI as docker compose (v2). It is mature, well-tested, and supported by virtually all CI/CD tools.
Podman Compose is a separate Python package that replicates Docker Compose functionality. Most standard docker-compose.yml files work without changes.
# Install podman-compose
pip3 install podman-compose
# Use it exactly like docker-compose
podman-compose up -d
podman-compose down
podman-compose logs
Where podman-compose has gaps:
- Docker Swarm mode — Podman does not support this. If you use Docker Swarm, migrating to Podman requires switching to Kubernetes first.
- Custom Docker plugins — not all Docker-specific extensions work
- Some advanced networking configurations need adjustment
For standard web application stacks (nginx, postgres, redis, app server), podman-compose works without changes.
CI/CD Pipelines
Docker works out of the box with GitHub Actions, GitLab CI, Jenkins, and CircleCI. Runners come pre-configured with Docker.
Podman in CI requires more setup but enables a security improvement that matters: you can build images in rootless mode without a privileged Docker daemon.
The traditional “Docker-in-Docker” approach in CI requires running the Docker daemon inside the CI container with privileged mode enabled. This is a known security risk — privileged containers have near-full access to the host.
With Podman, you build images rootless inside CI containers without privileged mode.
GitHub Actions with Podman:
name: Build with Podman
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Podman
run: sudo apt-get install -y podman
- name: Build image
run: podman build -t myapp:${{ github.sha }} .
- name: Push to registry
run: |
podman login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}
podman push myapp:${{ github.sha }} ghcr.io/${{ github.repository }}/myapp:${{ github.sha }}
Real-world example from the industry:
A SaaS company running GitLab CI switched from Docker-in-Docker (which required privileged CI containers) to Podman running rootless. This removes the need for privileged mode, which is often the reason security audits block Docker-in-Docker in the first place.
Image Compatibility
Both tools use the OCI image format. An image built with Docker runs on Podman and vice versa without conversion.
# Build with Docker, run with Podman
docker build -t myapp:latest .
podman run myapp:latest
# Build with Podman, push to Docker Hub
podman build -t myapp:latest .
podman push docker.io/yourusername/myapp:latest
Registry authentication — one difference to watch:
Podman stores registry credentials in $HOME/.config/containers/auth.json instead of Docker’s $HOME/.docker/config.json. When migrating CI pipelines, update credential paths accordingly.
Licensing — The Cost Difference
Docker Desktop:
Free for personal use, education, and companies with fewer than 250 employees and less than $10 million in annual revenue.
For larger organisations, per-user pricing on docker.com (checked September 2026, annual / monthly billing) is:
- Docker Pro: $9 / $11 per month
- Docker Team: $15 / $16 per month
- Docker Business: $24 per month
A team of 100 developers on Docker Business pays ~$28,800 per year just for the desktop client.
Podman Desktop:
Completely free. Open source. Apache License 2.0. No restrictions for commercial use.
Note: Docker Engine on Linux (not Docker Desktop) remains free for everyone. If your developers work on Linux, this licensing issue does not apply.
Adoption — The Numbers
From the Stack Overflow Developer Survey 2025 (all respondents):
- Docker: 71.1%, up 17 points from 2024, the largest one-year jump of any technology in the survey
- Podman: 11.1%
So Docker is not being replaced. Podman’s growth is concentrated where its model is a requirement rather than a preference: Red Hat-based platforms, rootless CI, and security-sensitive environments. And in production Kubernetes, neither tool runs your containers: the cluster uses containerd or CRI-O directly.
Common Migration Issues
Teams switching from Docker to Podman commonly hit three issues:
1. Registry authentication format:
# Docker stores credentials here
~/.docker/config.json
# Podman stores credentials here
~/.config/containers/auth.json
# Log in with Podman
podman login docker.io
2. Bind mount permissions: Rootless Podman maps your user to a different UID inside the container. Files created by the container may appear owned by a different user on the host.
# Fix: use --userns=keep-id to preserve user mapping
podman run --userns=keep-id -v ./data:/app/data myapp
3. Networking differences: Podman’s rootless networking uses slirp4netns or pasta. Port binding below 1024 may require additional configuration on some systems.
# If port 80 binding fails in rootless mode, use a higher port
podman run -p 8080:80 nginx
# Then use a reverse proxy (nginx, caddy) to forward 80 → 8080
Which One Should You Use?
Use Docker if:
- Your team is on Docker and it is working — no reason to change
- You use Docker Swarm for orchestration
- Your CI/CD tooling is tightly integrated with Docker and migration cost is high
- Developers work on macOS/Windows and your company is under the licensing threshold
- You need the broadest possible ecosystem compatibility
Use Podman if:
- You are on RHEL, Fedora, or CentOS — Podman is already installed and it is the supported default
- Security audits require rootless containers or a no-daemon architecture
- You are deploying to Kubernetes or OpenShift — Podman’s pod model reduces the gap between local dev and production
- You want to remove Docker Desktop licensing costs
- You run shared CI/CD servers where giving users Docker group access is a security concern
Use both if: This is what many mature teams actually do. Docker on developer machines for the familiar workflow and ecosystem. Podman in CI and production for security and Kubernetes alignment. The images are compatible so the switch between environments is seamless.
Quick Reference
| Feature | Docker | Podman |
|---|---|---|
| Architecture | Client-server with daemon | Daemonless, fork-exec |
| Runs as root by default | Yes | No |
| Rootless support | Available, not default | Default |
| Background daemon | Always running (dockerd) | None |
| Pod support | No | Yes |
| Kubernetes YAML generation | No | Yes (podman kube generate) |
| Systemd integration | Manual | Native |
| Docker CLI compatible | Native | Drop-in (alias docker=podman) |
| Compose | Docker Compose (built-in) | podman-compose (separate package) |
| Docker Swarm | Yes | No |
| Desktop licensing | Paid for large orgs | Free |
| Default in RHEL 8+ | No | Yes |
| Developer usage (SO survey 2025) | 71.1% | 11.1% |
| Enterprise security use | Standard | Preferred for regulated industries |
Frequently Asked Questions
For most workflows yes: the CLI is command-compatible and you can alias docker to podman. Differences show up with Docker Compose, the API socket and rootful-only tooling.
Podman runs containers without a daemon and defaults to rootless, so a container breakout does not land on a root-owned process. That is its main security advantage.
Yes. podman compose reads the same compose.yaml, and Podman can expose a Docker-compatible socket for the original docker compose.
Docker Engine and the CLI are free and open source. Docker Desktop requires a paid subscription for larger companies; Podman Desktop is free.
You Might Also Like
- 👉 Kubernetes Cost Optimization — 7 Ways to Cut Your Cloud Bill
- 👉 How to Run Ollama on a DigitalOcean Droplet
- 👉 DevSecOps Automation: Shift Left in CI/CD
Related guides
- how pods wrap containers in Kubernetes — Understanding Containers and Pods in Kubernetes
- Docker Desktop Licensing Cost: Pay or Switch?
- OpenTofu vs Terraform — Which IaC Tool Should You Use in 2026?
- Docker Best Practices: Navigating the Container Seas with Finesse
- Streamlining Container Management: A Guide to Docker and Container Registries
- Top 10 Essential Docker Commands Every Developer Should Know