Cloud Native 19 min read

Master Podman: A Complete Guide to Daemonless Container Management

This article provides a comprehensive overview of Podman, an open‑source, daemon‑less container runtime, comparing it with Docker, detailing its architecture, installation, configuration, common commands, image building, registry acceleration, user namespace setup, volume handling, and rootless port mapping for Linux systems.

dbaplus Community
dbaplus Community
dbaplus Community
Master Podman: A Complete Guide to Daemonless Container Management

What Is Podman?

Podman is an open‑source container runtime that runs on most Linux platforms. It offers Docker‑compatible commands while operating without a central daemon and can run without root privileges, managing any OCI‑compliant container or image.

Key Differences Between Podman and Docker

Docker requires a root‑owned daemon (dockerd) and multiple background services (containerd, containerd‑shim) to invoke the OCI runtime (runC).

Podman eliminates the daemon; it directly calls the OCI runtime (runC) via a lightweight conmon process, which acts similarly to Docker’s containerd‑shim.

Because Podman does not need a privileged daemon, its process tree is simpler and more secure.

The diagram below illustrates that Docker relies on a daemon layer, whereas Podman operates without one.

Usage Differences for System Builders and End Users

From a system‑builder perspective, Podman’s default tools differ mainly in process model and relationships; developers accustomed to Docker’s daemon‑based debugging must adapt to the daemon‑less approach, often using pstree to view the process hierarchy.

For end users, Podman’s CLI mirrors Docker’s commands for container lifecycle ( run, start, kill, ps, inspect), image handling ( images, rmi, pull, push), and even supports aliasing ( alias docker=podman) to achieve seamless transition.

Common Podman Commands

Container Management

podman run        # Create and start a container
podman start      # Start a stopped container
podman ps         # List containers
podman stop       # Stop a running container
podman restart    # Restart a container
podman attach     # Attach to a container
podman exec       # Execute a command in a container
podman export     # Export a container filesystem
podman import     # Import a container snapshot
podman rm         # Remove a container
podman logs       # View container logs

Image Management

podman search          # Search for images
podman pull            # Pull an image
podman images          # List local images
podman rmi             # Remove an image
podman save            # Export an image
podman load            # Import an image
podman build           # Build an image from a Dockerfile
podman tag             # Tag an image

Installing and Deploying Podman

# yum -y install podman

Configuring Registry Accelerators

Version 7

# vim /etc/containers/registries.conf
[registries.search]
registries = ["docker.io"]
[[docker.io]]
location = "j3m2itm3.mirror.aliyuncs.co"

Version 8

# vim /etc/containers/registries.conf
unqualified-search-registries = ["docker.io"]
[[registry]]
prefix = "docker.io"
location = "j3m2itm3.mirror.aliyuncs.com"

Basic Usage Examples

1. Run a container

[root@localhost ~]# podman run -d --name httpd docker.io/library/httpd
... (pull output omitted) ...

2. List running containers

[root@localhost ~]# podman ps
CONTAINER ID  IMAGE                     COMMAND      CREATED          STATUS          NAMES
0492e405...   docker.io/library/httpd    httpd-foreground  About a minute ago  Up About a minute ago  httpd

Adding -a shows all containers, not just running ones.

3. Inspect a container

[root@localhost ~]# podman inspect -l | grep IPAddress
"IPAddress": "10.88.0.5",

4. View container logs

[root@localhost ~]# podman logs --latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.5. Set the 'ServerName' directive globally to suppress this message

5. Monitor container processes

[root@localhost ~]# podman top httpd
USER   PID  PPID %CPU ELAPSED   TTY TIME COMMAND
root    1    0   0.000 15m38s   ?   0:00 httpd -DFOREGROUND
www-data 7   1   0.000 15m38s   ?   0:00 httpd -DFOREGROUND

6. Stop and remove a container

# podman stop --latest
# podman rm --latest

Building and Pushing an Image

Example Dockerfile (simplified):

FROM docker.io/library/centos
ENV PATH /usr/local/nginx/sbin:$PATH
ADD files/nginx-1.20.1.tar.gz /usr/src
RUN useradd -r -M -s /sbin/nologin nginx \
    && yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make \
    && cd /usr/src/nginx-1.20.1 \
    && ./configure \
       --prefix=/usr/local/nginx \
       --user=nginx \
       --group=nginx \
       --with-http_ssl_module \
       ...
    && make && make install
CMD ["nginx", "-g", "daemon off"]

Build, tag, login, and push:

# podman build -t nginx .
# podman tag docker.io/library/nginx:latest docker.io/1314444/test:latest
# podman login docker.io   # enter username/password
# podman push docker.io/1314444/test:latest

Rootless User Configuration

Install crun for cgroup v2 support and set it as the default OCI runtime:

# yum -y install crun
# vi /usr/share/containers/containers.conf
runtime = "crun"

Configure subuid/subgid for the non‑root user:

# yum -y install shadow-utils
# useradd zz
# echo "200000-201000" > /etc/subuid
# echo "200000-201000" > /etc/subgid
# sysctl -w net.ipv4.ping_group_range=0 200000

Key configuration files (order of precedence): containers.conf, storage.conf, registries.conf. User‑specific files in ~/.config/containers/ override system defaults.

Working with Volumes

Mount a host directory into a container as a volume:

# mkdir ~/data
# podman run -it -v "$(pwd)"/data:/data docker.io/library/busybox /bin/sh

When the container runs as root, files appear owned by root on the host. Use --userns=keep-id to preserve the host user’s UID/GID:

# podman run -it --name test -v "$(pwd)"/data:/data --userns=keep-id docker.io/library/busybox /bin/sh

Rootless Port Mapping

Rootless containers cannot bind privileged ports (< 1024) by default. Either map ports ≥ 1024 or adjust net.ipv4.ip_unprivileged_port_start:

# echo 'net.ipv4.ip_unprivileged_port_start=80' >> /etc/sysctl.conf
# sysctl -p
# podman run -d -p 80:80 httpd

This enables the container to listen on port 80 without root privileges.

Summary

Podman provides a Docker‑compatible, daemon‑less, rootless container experience, supporting full OCI compliance, flexible configuration, and easy image building and sharing. By configuring registries, storage, and user namespaces, developers can securely manage containers on Linux without the overhead of a privileged daemon.

LinuxContainer ManagementContainer RuntimePodmanDocker alternativeOCIrootless containers
dbaplus Community
Written by

dbaplus Community

Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.