OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 118

Docker and Podman: architecture, compatibility, and coexistence

Compare engine control models, permissions, and ecosystems to choose tools by workload.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSDocker: from running containers to application orchestration ↗Podman container workflows ↗
About 5 min readStart reading

One image standard, two entirely different philosophies. Understand dockerd and the daemonless model, and you understand the present and future of container engines.


The distinction in one sentence#

graph LR
    subgraph "容器的两个时代"
        D["Docker / 推动容器工作流普及 / Client-Server 架构 / 生态最成熟"]
        P["Podman / OCI 容器引擎 / Daemonless 架构 / 支持 rootless"]
    end
    D -->|"标准化了容器"| OCI["OCI 标准 / 镜像格式 / 运行规范"]
    P -->|"遵循同一标准"| OCI

Docker popularized image and container workflows and helped establish the OCI standards. Podman follows the same standards but reimplements them with a completely different architecture.


Architecture comparison: a concierge vs doing it yourself#

Docker:
  docker CLI  ──REST API──▶  dockerd (ROOT, 常驻)  ──▶  containerd  ──▶  runc
                              └─ 所有操作都经过它
                              └─ 它是唯一的控制点

Podman:
  podman CLI  ──直接 fork/exec──▶  conmon  ──▶  crun/runc
               └─ 每次启动新进程
               └─ 没有中央控制点

What does this difference mean?

Aspect Docker Podman
Background processes dockerd runs continuously; resource usage depends on workload No persistent central daemon; containers still have processes such as conmon
Privilege model Traditionally a rootful daemon; rootless is also supported Supports rootful and rootless, depending on the running user and configuration
Single point of failure An unavailable daemon affects management; live-restore helps in some runtime scenarios No persistent central daemon is required, but containers still share the host kernel and resources
Startup at boot dockerd starts at boot; containers use restart policies Managed through systemd + Quadlet
API approach dockerd's REST API (the socket is an attack surface) Optional Podman API and Docker-compatible API services/sockets; all require controlled permissions
Container lifecycle daemon/containerd/shim cooperate to control the lifecycle Containers are independent user processes

An analogy

  • Docker is like staying in a hotel: the front desk (dockerd) is staffed 24 hours a day, and everything (check-in, check-out, room service) goes through it. The front desk has a master key (root).
  • Podman is like living in your own house: you open the door, turn off the lights, and cook for yourself. Local operations do not need a continuously staffed front desk; rootful operation or an API socket can still grant high privileges.

Compatibility: Docker syntax, Podman engine#

Command-line compatibility

# 这两个命令几乎等价
docker run -d --name web -p 8080:80 nginx:alpine
podman run -d --name web -p 8080:80 nginx:alpine

# 简单 CLI 可用 alias 试验,但脚本/API/Compose/buildx/远程行为需逐项验证
alias docker=podman
docker ps          # 实际跑的是 podman ps
docker build -t myapp .  # 实际跑的是 podman build

Ecosystem compatibility

Docker tool Podman equivalent
Docker Compose podman-compose or podman.socket + docker compose
Docker Desktop Podman Desktop (free and open source)
Docker Hub The same; both use docker.io
Dockerfile Common syntax is shared; verify advanced BuildKit features and version support. podman build reads Dockerfiles directly
Docker Swarm Not supported by Podman; use Kubernetes workflows or other orchestration. generate kube only produces compatible configuration fragments, not a direct deployment migration

Compatibility boundaries

Common areas of interoperability (still verify by version):

  • Image format (OCI standards)
  • Dockerfile syntax
  • Basic CLI commands (run, ps, stop, pull, push, build)
  • Volumes and bind mounts
  • Port mapping (subject to rootless port restrictions)
  • Environment variable injection

Incompatibilities:

  • Differences in implementation support for Compose deploy; deploy.resources is not exclusive to Swarm and cannot be declared unsupported across the board
  • Docker Swarm as a whole
  • Multi-driver builds with docker buildx (Podman uses podman build --platform)
  • docker context (Docker's feature for switching between multiple environments)

Security: fundamental differences#

# Docker(默认):docker run 通过 dockerd socket 执行
# 父进程可能是 shim,权限由 daemon/rootless、userns 和容器 USER 等共同决定
sudo docker run -d nginx:alpine
ps aux | grep nginx
# 示意:ps 的 USER 列是进程用户,不显示父进程;查看父关系另查 PPID

# Podman rootless:进程位于用户映射的权限范围,父关系与用户身份不是同一概念
podman run -d nginx:alpine
ps aux | grep nginx
# 示意:宿主可见 UID 取决于用户命名空间映射

Key security facts:

  • A user who controls the rootful Docker API can generally obtain capabilities close to host root; a rootless API is limited to the corresponding user's privileges. A rootful administrator can access sensitive host content through operations such as privileged mounts. Rootless operation does not thereby grant arbitrary file-read access
  • In rootless Podman, container UID 0 usually maps to the launching user, while other UIDs can map to subordinate IDs. This reduces exposure of host root, but user files, mounts, sockets, and kernel vulnerabilities still present risks

Choosing an engine#

graph TD
    A["我需要什么?"] --> B{"需要 Docker 专属功能?"}
    B -->|"Docker Swarm"| D["用 Docker"]
    B -->|"Docker Build Cloud"| D
    B -->|不需要| C{"运行环境?"}
    C -->|"个人开发机"| E["Podman / 按 rootless 与工具链要求验证"]
    C -->|"生产服务器"| F{"用什么管理?"}
    F -->|"systemd"| G["Podman + Quadlet / 声明式 + 原生集成"]
    F -->|"Compose 文件"| H{"单机还是集群?"}
    H -->|"单机"| I["Docker 或 Podman / 看团队习惯"]
    H -->|"集群"| J["Docker Swarm 或 K8s"]
    C -->|"公司强制"| K["用公司的标准 / 通常 Docker"]

Specific recommendations

Your situation Recommendation Reason
Learning containers Podman Open source with similar common commands; verify interoperability for the actual workload
Personal projects Podman No persistent central daemon, with rootless available; measure resource use and security in practice
Your team uses Docker Docker Stay consistent and reduce collaboration friction
Company projects Docker Enterprise support and mature CI/CD integration
Single-host production deployment Podman + Quadlet systemd management, automatic restarts, and unified logging
Production cluster deployment Docker Swarm or K8s Orchestration capabilities
Security-sensitive environments Evaluate Podman rootless or Docker rootless Define privilege, isolation, and compatibility requirements clearly

History and version boundaries#

Docker began popularizing container image workflows in 2013. The OCI was established in 2015 and accepted contributions including runc. Podman subsequently developed into an OCI engine emphasizing local operation without a persistent central daemon and support for rootless operation. Quadlet, networking, API, and Desktop features continue to evolve; a particular major version number should not be treated as the point when all features first appeared.

Docker Desktop licensing, Hub quotas, and distribution defaults can change; they do not prove container-format compatibility. Check a distribution's default engine and the requirements for coexistence on one machine against actual packages, sockets, and version configuration. Choosing an engine requires checking the actual version, container configuration, and team toolchain.

Coexistence: Docker and Podman on the same machine#

# 两者可在同台机器并存,分别管理存储;端口、CLI/socket 兼容包和资源仍可能冲突
sudo docker run -d nginx:alpine        # Docker 容器
podman run -d nginx:alpine             # Podman 容器(rootless)

# 查看 Docker 容器
sudo docker ps

# 查看 Podman 容器
podman ps

# 镜像互导
podman save nginx:alpine -o nginx.tar
sudo docker load -i nginx.tar
# 反之亦然

Main takeaway#

Docker and Podman share common image standards, registries, and Dockerfile workflows, but their privilege models, APIs, build features, and orchestration are not guaranteed to be fully interchangeable. Choose based on security boundaries, team tooling, platform, and maintenance approach, and test compatibility with the actual application when necessary. Daemonless operation is not an absolute security guarantee, and rootless operation is not unique to Podman.

References & further reading

  1. Docker rootless ↗
  2. Docker daemon security ↗
  3. Podman API service ↗
  4. Podman Compose provider ↗
  5. OCI specifications ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

Docker: from running containers to application orchestration

  1. 01Docker basics: images, containers, and the daemon
  2. 02The Docker command line: images, containers, volumes, and networks
  3. 03Dockerfiles and image builds
  4. 04Compose: defining multi-service applications
  5. 05Docker networking and storage
  6. 06Docker in production: resources, security, and recovery
  7. 07Declaring Docker and containers on NixOS
  8. 08Swarm: from service replicas to cluster orchestration
  9. 09Docker and Podman: architecture, compatibility, and coexistence

Podman container workflows

  1. 01Podman fundamentals
  2. 02A basic Podman usage guide
  3. 03Rootless containers: whose file permissions count?
  4. 04Rootless configuration: mappings, ICMP, and registries
  5. 05Pods and Kubernetes manifests
  6. 06How does Quadlet turn container declarations into services?
  7. 07Pods and multi-service configuration with Quadlet
  8. 08Compose providers and interoperability with Docker tools
  9. 09Managing Podman on NixOS
  10. 10Advanced Podman operations and tuning
  11. 11Docker and Podman: architecture, compatibility, and coexistence
CONTINUE READING / NEXT ARTICLEPodman fundamentals

Understand Podman's architecture and permission model through containers, images, and OCI runtimes.