Subscribe to the feed

In previous articles, my containers team colleagues Dan Walsh and Brent Baude shared some cool Podman features to try, including flags to modify how to run containers and various Podman commands to simplify how users interact with containers.

Now it's my turn to highlight features that can be useful when automating Podman and its containers and pods. If you're hungry for some more exclusive and surprisingly useful Podman features, please read on.

1. Generate a systemd unit file

Podman's fork-exec architecture makes running containers with systemd as simple as writing a unit file. This allows systemd to manage the container as a service, which can be useful for containers that you want to automatically start on system boot or restart if the container fails.

[ Download the systemd commands cheat sheet. ]

For example, create a containerized webserver:

$ podman run -d  --name myserver  -p 8000:80 nginx
F1daddc385d7a3cf8ac57ef12e7bfe7825ee96c8bc5abdf8f2439db6c3c916a2

It's probably a good idea to ensure the web server is always up and running because little is more frustrating than trying to reach a web page that is down. Therefore, running this container as a systemd service is a good idea because systemd can detect if the Podman process exits and automatically restart the container.

To do this, you need to create a systemd unit file and make systemd aware of it. The command podman generate systemd automatically creates the unit file from the existing container:

$ mkdir -p ~/.config/systemd/user/
$ podman generate systemd --new myserver > ~/.config/systemd/user/myserver.service

Restart the systemd daemon and start the container using systemd:

$ systemctl --user daemon-reload
$ systemctl --user start myserver.service
$ podman ps
CONTAINER ID  IMAGE                           COMMAND               CREATED        STATUS            PORTS                 NAMES
7444bcf61e17  docker.io/library/nginx:latest  nginx -g daemon o...  4 seconds ago  Up 5 seconds ago  0.0.0.0:8000->80/tcp  myserver

If the containerized webserver fails, systemd will automatically restart the container. Note that the default restart policy for podman generate systemd is "on failure," but you can easily adjust it using the --restart-policy flag. The podman generate systemd command is not limited to containers; it can also create unit files for pods.

Starting with Podman v4.2, you can also run Kubernetes workloads in systemd with Podman.

2. Display `podman top` format descriptors

The podman top command displays information about a container's running processes. By default, running podman top outputs data similar to running ps -ef inside the container:

$ podman top myserver
USER        PID         PPID        %CPU        ELAPSED       TTY         TIME        COMMAND
root        1           0           0.000       5.244439467s  ?           0s          nginx: master process nginx -g daemon off;
nginx       26          1           0.000       5.244536883s  ?           0s          nginx: worker process

The podman top command also takes format descriptors. Podman supports all AIX format descriptors for ps. For example, display the PID, User, and %CPU information:

$ podman top myserver %p %U %C
PID         USER        %CPU
1           root        0.000
26          nginx       0.000

Podman implements additional format descriptors that are more useful in a container context. These are host format descriptors that describe information on the process running inside the container from the host's perspective. For example, the hpid and hgroup format descriptors show the PID and the process' group on the host:

$ podman top myserver user pid hpid group hgroup
USER        PID         HPID        GROUP       HGROUP
root        1           2016        root        1000
nginx       26          2042        nginx       100100

Other host format descriptors include different permissions such as SELinux labels, seccomp policy, and permitted capabilities:

$ podman top myserver user pid label seccomp capprm
USER        PID         LABEL                                        SECCOMP     PERMITTED CAPS
root        1           system_u:system_r:container_t:s0:c270,c795  filter      CHOWN,DAC_OVERRIDE,FOWNER,FSETID,KILL,NET_BIND_SERVICE,SETFCAP,SETGID,SETPCAP,SETUID,SYS_CHROOT
nginx       26          system_u:system_r:container_t:s0:c270,c795  filter      none

Host format descriptors are especially useful when trying to debug a container from the host's perspective because they give insight into how the processes in the container are set up and behave.

[ Download now: Podman basics cheat sheet. ]

3. Use Podman's auto-update feature

Often, container images on registries will be updated due to a newer release or a simple rebuild. If a container runs a certain image, it might be useful to have the most recent build of the image running. Auto-update allows Podman to keep containers current by pulling newer versions of images and restarting containers automatically as needed. The auto-update function is available only for containers run by systemd unit files.

Auto-update can be demonstrated by intentionally pulling an older version of the Fedora image and tagging it as fedora:latest:

$ podman pull fedora:35
$ podman tag fedora:35 registry.fedoraproject.org/fedora:36

Now, create a container with auto-update enabled and use the "outdated" Fedora image. To do this, you need to label the container to auto-update when the registry has a newer image:

$ podman create --name mycontainer --label io.containers.autoupdate=registry registry.fedoraproject.org/fedora:36 sleep infinity
3c7bd3d4f0c9fa315a071e8cdc2f85c529d6455e2acfb5f8a06752669eb84713

Because auto-update works only with containers managed with systemd, you need to use the podman generate systemd command to create a unit file:

$ mkdir -p ~/.config/systemd/user/
$ mkdir -p ~/.config/systemd/user/
$ podman generate systemd --new mycontainer > ~/.config/systemd/user/mycontainer.service
$ systemctl --user daemon-reload
$ systemctl --user start mycontainer.service
$ podman ps
CONTAINER ID  IMAGE                                 COMMAND         CREATED        STATUS            PORTS       NAMES
bb84d78f375c  registry.fedoraproject.org/fedora:36  sleep infinity  2 seconds ago  Up 2 seconds ago              mycontainer

Now, if you run podman auto-update, Podman will detect that the local image is outdated, pull the latest version from the registry, and restart the systemd service:

$ podman auto-update
Trying to pull registry.fedoraproject.org/fedora:36...
Getting image source signatures
Copying blob 878a8677dead skipped: already exists  
Copying config 307241a058 done  
Writing manifest to image destination
Storing signatures
UNIT                 CONTAINER                   IMAGE                                 POLICY      UPDATED
mycontainer.service  bb84d78f375c (mycontainer)  registry.fedoraproject.org/fedora:36  registry    true

Most Linux distributions ship Podman with an auto-update systemd timer and an auto-update service. This configuration allows you to set time and event triggers for auto-updates, so you do not have to run the podman auto-update command manually. For a more in-depth view of auto-update, please see How to use auto-updates and rollbacks in Podman.

4. Try Podman's `–-pull=never` flag

Automatically updating containers is convenient for containers that need to be on the latest version of an image. However, some users may want to decide when (and if) they want to pull images when running containers or building images. Podman's run, create, and build commands have a --pull flag that allows you to specify when to pull images from remote registries. By default, the pull policy is set to "missing," which means that Podman will pull an image if it does not exist in local storage.

The -–pull command-line option has three valid values: always, missing, and never. When pull is set to always, Podman will always attempt to pull an image and fail if the image cannot be pulled—even if the image already exists in local storage. The missing value implies Podman will pull only if the image does not exist already in local storage. And for the most stability, you can use never. This value ensures Podman will never pull from a registry and will only use images found in your local storage.

$ podman build --pull=never .
STEP 1/2: FROM alpine
Error: error creating build container: alpine: image not known

5. Compare the `libpod` and `docker-compat` APIs

Podman's REST API is well-loved and powerful for managing containers. If you have read the API documentation, you've seen there are a bunch of sections with the compat label. Initially, it may look like there are duplicate endpoints but with some differences in parameters and body schemas.

[ Getting started with containers? Check out this no-cost course: Deploying containerized applications: A technical overview. ]

Podman's API actually comes in two flavors: libpod and docker-compat. When writing our REST API, we realized that Podman has many features that Docker does not have, including pod management, manifest actions, and a bunch of extra options for container, image, network, and volume management.

At the same time, we want our API to be compatible with Docker's API because many applications already use the Docker API, and many developers have existing scripts designed for Docker API. So, we did just that: Our compat API is nearly identical to Docker's API, which means you can run almost any script or application against Podman's compat API for easy migration!

And if you want to take advantage of powerful and exclusive Podman features, the libpod API is the place to go. Even better, both sets of API endpoints can be used at the same time.

Wrap up

Podman is chock full of cool and interesting features that extend beyond just building and running containers. These five Podman features come in handy when automating tasks with Podman.

The podman generate systemd command makes writing unit files painless, and auto-update ensures that your image is always, well, up-to-date. The podman top format descriptors make it easy to debug and monitor processes inside the container, especially using host options. The --pull=never flag guarantees stability in which image is used when running or building containers. Finally, the dual-mode API allows users to migrate to Podman and take advantage of Podman's more unique features.

These commands, flags, and API flavors simplify and help automate day-to-day container workflows.


About the author

Ashley Cui is a software engineer at Red Hat, working on Podman, Buildah, and other container tools.

Read full bio
UI_Icon-Red_Hat-Close-A-Black-RGB

Browse by channel

automation icon

Automation

The latest on IT automation for tech, teams, and environments

AI icon

Artificial intelligence

Updates on the platforms that free customers to run AI workloads anywhere

open hybrid cloud icon

Open hybrid cloud

Explore how we build a more flexible future with hybrid cloud

security icon

Security

The latest on how we reduce risks across environments and technologies

edge icon

Edge computing

Updates on the platforms that simplify operations at the edge

Infrastructure icon

Infrastructure

The latest on the world’s leading enterprise Linux platform

application development icon

Applications

Inside our solutions to the toughest application challenges

Original series icon

Original shows

Entertaining stories from the makers and leaders in enterprise tech