Mastering Podman Deployment and Configuration on Ubuntu 20.04 LTS

The evolution of containerization has shifted from monolithic, daemon-based architectures toward more flexible, secure, and decentralized models. Podman, an open-source, daemonless, and rootless container engine, represents the pinnacle of this shift. While newer Ubuntu releases integrate Podman into their primary repositories, Ubuntu 20.04 LTS (Focal Fossa) requires a more nuanced approach to installation and configuration due to its position in the OS lifecycle. Implementing Podman on this specific version allows administrators and developers to leverage Open Container Initiative (OCI) compliant images without the security vulnerabilities inherent in a root-privileged daemon. This guide provides an exhaustive technical deep dive into the installation, optimization, and integration of Podman on Ubuntu 20.04, ensuring a production-ready environment for modern microservices.

The Architectural Advantages of Podman

Before proceeding with the technical implementation, it is critical to understand why Podman is selected over traditional alternatives like Docker, especially in an enterprise Ubuntu 20.04 environment.

The daemonless nature of Podman is its most significant architectural departure. Unlike Docker, which relies on a persistent background process (the Docker Daemon) to manage containers, Podman utilizes a fork-exec model. When a user executes a Podman command, the process is launched directly. This eliminates the single point of failure associated with a daemon; if the daemon in a traditional setup crashes, all managed containers may be affected. In Podman, the container's lifecycle is independent of a central service.

Rootless operation is the cornerstone of Podman's security model. By leveraging user namespaces, Podman allows non-privileged users to run containers. In a rootful environment, a container escape vulnerability could grant an attacker root access to the host machine. In a rootless configuration, the user is the root inside the container, but remains a standard unprivileged user on the host, drastically reducing the attack surface.

Podman maintains strict OCI compliance and Docker CLI compatibility. Because it follows the Open Container Initiative standards, it can run any image created by Docker or other OCI-compliant tools. The CLI is designed to be a drop-in replacement, meaning the majority of commands used in the Docker ecosystem work identically in Podman, facilitating a seamless transition for DevOps teams.

Finally, Podman introduces native support for "Pods." Borrowed from the Kubernetes concept, a pod is a group of one or more containers that share the same network namespace and storage volumes. This allows for the orchestration of tightly coupled services without requiring a full Kubernetes cluster, providing a bridge for developers moving from local development to K8s production environments.

Installation Pathways for Ubuntu 20.04

Ubuntu 20.04 does not include Podman in its default official repositories in the same manner as Ubuntu 22.04 or 24.04. Therefore, users must utilize the Kubic project repository to access stable builds.

The Kubic Repository Implementation

The Kubic project provides a specialized build service for container tools. To install Podman on Ubuntu 20.04, the system must be pointed to the OpenSUSE build service repositories.

First, ensure the system is updated and possesses the necessary certificates for secure communication:

sudo apt update

sudo apt install ca-certificates

The installation process utilizes the VERSION_ID from the /etc/os-release file to ensure the correct repository branch is targeted. The following sequence of commands adds the repository and the corresponding GPG key to verify the integrity of the downloaded packages:

. /etc/os-release

echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list

curl -L "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/Release.key" | sudo apt-key add -

Once the repository is established, the package index must be refreshed before the final installation:

sudo apt update

sudo apt -y upgrade

sudo apt -y install podman

This method ensures that the user receives a version of Podman that is compatible with the glibc and kernel versions present in the 20.04 LTS environment.

Advanced Configuration and System Tuning

A default installation of Podman is functional but not optimized for production or rootless operations. Technical tuning of the storage and container configuration is required to ensure stability.

Rootless User Initialization

To initialize a rootless environment, the user must execute the podman info command. This triggers the creation of the necessary user-space configuration files and validates the environment's readiness for unprivileged containers.

podman info

For rootless containers to function, the system must map the user's ID to a range of subordinate UIDs and GIDs. This allows the container to simulate a root user inside the namespace while remaining unprivileged on the host. The following commands assign a range of 65,536 IDs starting from 100,000 to the current user:

echo "$USER:100000:65536" | sudo tee /etc/subuid

echo "$USER:100000:65536" | sudo tee /etc/subgid

The containers.conf Optimization

The global configuration file, containers.conf, controls the behavior of the container engine. To configure the system, first copy the sample configuration to the active directory:

sudo cp -v /usr/share/containers/containers.conf /etc/containers/

Using a text editor, navigate to /etc/containers/containers.conf and modify the following parameters to ensure compatibility with Ubuntu's systemd and logging architecture:

  • Update cgroup_manager from "systemd" to "cgroupfs". This change is often necessary in specific 20.04 kernel configurations to avoid cgroup hierarchy conflicts.
  • Update events_logger from "journald" to "file". This redirects event logging to a file, which can be more accessible for debugging in some virtualized environments.

Furthermore, the system limits (ulimits) must be increased to prevent "too many open files" errors during high-load operations. In the [containers] section of the file, apply the following settings:

[containers]
default_ulimits = [
"nofile=65535:65535",
"memlock=-1:-1"
]

Note that these ulimits configurations are primarily effective for rootful Podman. If applied to a rootless environment, they may trigger permission errors as unprivileged users cannot override system-level resource limits via this configuration file.

Registry and Storage Management

Podman requires a defined list of registries to search for images when a fully qualified domain name (FQDN) is not provided. This is managed in registries.conf.

To view the current registry settings:

cat /etc/containers/registries.conf

To add Docker Hub, Quay.io, and GitHub Container Registry to the search list, edit the file using sudo nano /etc/containers/registries.conf and add:

[registries.search]
registries = ['docker.io', 'quay.io', 'ghcr.io']

For rootless storage, Podman utilizes the overlay filesystem. To configure this, a user-specific directory must be created:

mkdir -p ~/.config/containers

nano ~/.config/containers/storage.conf

Insert the following configuration to specify the fuse-overlayfs mount program, which is required for rootless overlay mounts on Ubuntu 20.04:

[storage]
driver = "overlay"

[storage.options]
mount_program = "/usr/bin/fuse-overlayfs"

Docker Compatibility and Tooling Integration

For organizations transitioning from Docker, Podman provides several compatibility layers to ensure that existing scripts and workflows remain operational.

Aliasing and the Compatibility Layer

The simplest way to maintain compatibility is by aliasing the docker command to podman in the shell configuration.

echo "alias docker=podman" >> ~/.bashrc

source ~/.bashrc

For a more robust integration, the podman-docker package can be installed. This package creates a symbolic link from /usr/bin/docker to /usr/bin/podman, ensuring that any third-party script calling the docker binary will actually execute Podman.

sudo apt install podman-docker -y

which docker

Docker Compose and Podman-Compose

While Podman can run individual containers, the need for multi-container orchestration is handled by podman-compose. This tool allows users to utilize docker-compose.yml files.

Installation can be performed via the package manager:

sudo apt install podman-compose -y

Alternatively, for the most recent version, use the Python package installer:

pip3 install podman-compose

With this installed, the standard command to launch a multi-container stack is:

podman-compose up -d

Working with Pods and Image Building

Podman extends the container concept by allowing the creation of pods, which are essential for microservice architectures.

Pod Lifecycle Management

A pod allows multiple containers to share a network IP and ports. To create a pod and map a port (e.g., 8080 to 80):

podman pod create --name mypod -p 8080:80

Containers can then be added to this pod:

podman run -d --pod mypod --name web nginx

podman run -d --pod mypod --name app myapp

To manage these entities, use the following commands:

podman pod ps

podman pod stop mypod

podman pod rm mypod

Image Construction with Podman and Buildah

Podman can build images directly from a Dockerfile:

podman build -t myimage:latest .

podman build -f Dockerfile.prod -t myimage:prod .

podman build --build-arg VERSION=1.0 -t myimage:v1 .

For more advanced image construction, Buildah is recommended. Buildah allows for the creation of images without requiring a Dockerfile, enabling a more programmatic approach to image building.

sudo apt install buildah -y

The process involves creating a working container from a base image, executing commands within it, and then committing the changes:

container=$(buildah from ubuntu)

buildah run $container apt-get update

buildah run $container apt-get install -y nginx

buildah config --cmd

Integration with Cockpit for Graphical Management

For administrators who prefer a web-based interface, Podman can be integrated into Cockpit, a server administration tool.

Installing Cockpit and Podman Controller

Cockpit is available in the Ubuntu 20.04 multiverse repository:

sudo apt update && sudo apt install -y cockpit

To add the Podman controller, the cockpit-podman repository must be cloned and built, as it may not be available as a simple package in older 20.04 versions:

git clone https://github.com/cockpit-project/cockpit-podman.git

Build Requirements and Dependencies

The build process for the Cockpit Podman extension requires specific tools. appstream-util and build-essential are mandatory:

sudo apt update && sudo apt install -y appstream-util build-essential

It is also critical to install a current version of nodejs. The version provided by the Ubuntu 20.04 package maintainer is often several major versions behind and may cause build failures. A manual installation of a recent Node.js LTS version is recommended.

Low-Level Runtime Requirements and Compilation

For those building Podman from source or requiring specific runtime behaviors, understanding the underlying dependencies is essential.

The Go Language Environment

As of August 2025, version 1.23.x or higher of the Go programming language is required. If the system Go version is outdated, it can be built from source:

export GOPATH=~/go

git clone https://go.googlesource.com/go $GOPATH

cd $GOPATH

cd src

./all.bash

export PATH=$GOPATH/bin:$PATH

Conmon and Container Runtimes

Podman relies on conmon (container monitor) to manage the OCI runtime. Conmon monitors the container and handles the terminal. To build it from source:

git clone https://github.com/containers/conmon

cd conmon

export GOCACHE="$(mktemp -d)"

make

sudo make podman

Additionally, an OCI-compliant runtime must be installed. crun and runc are the primary choices, with crun taking priority.

  • runc: Minimum version v1.1.11 is required.
  • crun: Minimum version v1.14.3 is required.

To verify the installed version of the runtime:

runc --version

Technical Specifications Summary

The following table summarizes the critical components and requirements for Podman on Ubuntu 20.04.

Component Requirement/Value Purpose
OS Version Ubuntu 20.04 LTS Host Operating System
Repository Kubic (OpenSUSE) Source for Podman binaries
Go Version 1.23.x or higher Compilation requirement
runc Version $\ge$ v1.1.11 OCI Runtime
crun Version $\ge$ v1.14.3 OCI Runtime (High Priority)
Storage Driver overlay / fuse-overlayfs Layered filesystem management
Cgroup Manager cgroupfs Resource grouping and limiting

Conclusion

Deploying Podman on Ubuntu 20.04 LTS provides a robust, secure, and flexible alternative to traditional daemon-based container engines. By utilizing the Kubic repositories, administrators can bypass the limitations of the default 20.04 package set. The transition to rootless operation, enabled by the configuration of /etc/subuid and /etc/subgid, significantly enhances the security posture of the host by mitigating the risks of container breakouts.

The integration of podman-compose and the podman-docker compatibility layer ensures that existing DevOps pipelines are not disrupted, while the adoption of "Pods" prepares the infrastructure for future migration to Kubernetes. Whether through the command line or the Cockpit graphical interface, Podman on Ubuntu 20.04 offers a scalable path toward modern containerization, provided that the underlying runtimes (crun/runc) and storage drivers (fuse-overlayfs) are correctly aligned with the system's kernel capabilities.

Sources

  1. Hitesh Jethva - How to Install and Use Podman on Ubuntu 20.04
  2. OneUptime - Install and Configure Podman on Ubuntu
  3. Podman Official Installation Documentation
  4. Develmonk - Add Podman Controller to Cockpit on Ubuntu 20.04 LTS
  5. GitHub Gist - Podman Installation Guide

Related Posts