Docker Demystified - Part 7: Podman — Red Hat's Daemonless Container Engine

What is Podman?

Podman (Pod Manager) is Red Hat’s answer to Docker. It’s a daemonless container engine designed as a drop-in replacement.


The Key Architectural Difference

DOCKER:
┌────────┐    ┌────────┐    ┌───────────┐    ┌─────────────┐    ┌──────┐
│ docker │ ─▶ │dockerd │ ─▶ │containerd │ ─▶ │containerd-  │ ─▶ │ runc │
│  CLI   │    │(daemon)│    │ (daemon)  │    │    shim     │    │      │
└────────┘    └────────┘    └───────────┘    └─────────────┘    └──────┘
                  ▲              ▲
             Always running (2 daemons)


PODMAN:
┌────────┐                      ┌────────┐    ┌──────┐
│ podman │ ─────────────────▶   │ conmon │ ─▶ │ crun │
│  CLI   │   (direct fork)      │ (shim) │    │      │
└────────┘                      └────────┘    └──────┘
     │
No daemon! Each command is independent.

Podman Doesn’t Use containerd

This surprises people. Podman handles everything that containerd would do, but built into the podman binary itself:

containerd’s JobHow Podman Handles It
Image managementBuilt-in (containers/image library)
Container lifecycleBuilt-in
Storage/snapshotsBuilt-in (containers/storage library)
Calling OCI runtimePodman calls crun/runc directly

Podman is a monolithic tool. Everything in one binary. No daemons.


Default Low-Level Runtimes

EngineDefault OCI Runtime
Dockerrunc
Podmancrun

Red Hat chose crun for Podman because:

  • Smaller: ~300 KB vs runc’s ~10 MB
  • Faster: Lower startup latency
  • Better rootless support: Designed with unprivileged execution in mind

The Rootless Advantage

Traditional Docker runs as root:

DOCKER (rootful):

You (regular user)
   │
   │  docker run nginx
   ▼
┌─────────────────────────────────────────────────┐
│  dockerd (running as ROOT)                      │
│     │                                           │
│     │  Has full system access                   │
│     │  Can do ANYTHING on the host              │
│     ▼                                           │
│  container                                      │
└─────────────────────────────────────────────────┘

Security risks:
• Container escape = full root on host
• Daemon vulnerability = full system compromise
• Any user in "docker" group = effectively root

Podman runs rootless by default:

PODMAN (rootless):

You (regular user, UID 1000)
   │
   │  podman run nginx
   ▼
┌─────────────────────────────────────────────────┐
│  podman (running as YOU, no daemon)             │
│     │                                           │
│     │  Uses user namespaces                     │
│     │  "root" in container = UID 100000 on host │
│     ▼                                           │
│  container                                      │
│  (thinks it's root, but mapped to unprivileged) │
└─────────────────────────────────────────────────┘

Security benefits:
• Container escape = still just regular user
• No daemon to attack
• No special group membership needed

How User Namespace Mapping Works

Inside container          On host system
────────────────          ──────────────
 UID 0 (root)      ───▶    UID 100000 (unprivileged)
 UID 1             ───▶    UID 100001
 UID 2             ───▶    UID 100002
...

The container THINKS it's root.
The host sees an unprivileged user.
Container escape = attacker gains nothing.

CLI Compatibility

Podman’s CLI is intentionally identical to Docker’s:

# These commands are interchangeable:
docker run -d -p 8080:80 nginx
podman run -d -p 8080:80 nginx

docker build -t myapp .
podman build -t myapp .

docker push registry.example.com/myapp
podman push registry.example.com/myapp

# You can even alias it:
alias docker=podman

Podman’s Unique Feature: Native Pod Support

Podman understands Kubernetes pods natively:

# Create a pod (like a K8s pod)
podman pod create --name myapp -p 8080:80

# Add containers to the pod — they share network namespace
podman run -d --pod myapp nginx
podman run -d --pod myapp redis

# Containers can reach each other via localhost
# nginx can connect to redis at localhost:6379
# Just like in Kubernetes
# Generate Kubernetes YAML from running pod
podman generate kube myapp > deployment.yaml

Docker doesn’t have native pod support. You’d use Compose or manual networking.


Podman Architecture Components

conmon (Container Monitor)

Similar to containerd-shim, but simpler:

  • Monitors container process
  • Keeps I/O streams open
  • Reports exit status
  • One conmon per container

crun (OCI Runtime)

Red Hat’s fast, lightweight OCI runtime:

  • Written in C (vs runc in Go)
  • Lower memory usage
  • Faster startup
  • Better rootless support

Rootful vs Rootless Podman

Podman can run both ways:

# Rootless (default) - safer, no privileges needed
podman run nginx

# Rootful - when you need real root (privileged operations)
sudo podman run nginx

When to use rootful:

  • Binding to privileged ports (< 1024) without port mapping
  • Accessing hardware devices
  • Mounting certain filesystems
  • Running legacy containers that assume root

Most of the time, rootless is fine.


Podman on Mac and Windows

Just like Docker Desktop, Podman needs a Linux VM on non-Linux systems:

# Initialize Podman machine (first time)
podman machine init

# Start the VM
podman machine start

# Now podman commands work
podman run nginx

The VM is managed by podman machine commands.


Podman Desktop

Red Hat provides a GUI application similar to Docker Desktop:

  • Visual container management
  • Image building
  • Kubernetes YAML generation
  • Extension system
  • Always free - No licensing restrictions

When Podman Shines

  1. Security-conscious environments - Rootless by default
  2. Enterprise without Docker licenses - Always free
  3. Kubernetes development - Native pod support
  4. CI/CD pipelines - No daemon to manage
  5. OpenShift deployments - Consistent with production

When Docker Might Be Better

  1. Docker Compose heavy workflows - Better integration
  2. Existing Docker Desktop workflows - No need to change
  3. Third-party tool integration - More tools support Docker
  4. Learning resources - More tutorials use Docker

Can They Coexist?

Yes, but carefully:

# Both use different storage locations by default
docker info | grep "Storage Driver"  # /var/lib/docker
podman info | grep "Storage Driver"  # ~/.local/share/containers

# They don't see each other's images/containers
docker ps      # Shows Docker containers
podman ps      # Shows Podman containers

To share images, use a registry as the source of truth.


Key Takeaways

  1. Podman = daemonless - No background processes
  2. Rootless by default - Better security model
  3. Drop-in Docker replacement - Same CLI commands
  4. Native pod support - Kubernetes-friendly
  5. Uses crun - Faster, lighter OCI runtime
  6. Always free - No enterprise licensing
  7. Built-in libraries - Doesn’t need containerd
  8. OpenShift standard - Red Hat’s choice

Comments