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
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
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
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
$ 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
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.
-–pull command-line option has three valid values:
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.
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.
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.