Install Podman Howsnip

How to Install Podman on Ubuntu and Run Containers Without Docker

Podman is a modern, daemonless container engine that allows you to run OCI-compatible containers without requiring a long-running root daemon. Unlike Docker, Podman starts containers as regular user-owned processes, making it a popular choice for users who want a more secure and lightweight container runtime.

In this tutorial, you’ll learn how to install Podman on Ubuntu, verify rootless container support, run your first container, build custom images, create pods, and even configure containers to start automatically with systemd.

Prerequisites

  • A supported Ubuntu system
  • A user account with sudo privileges
  • Internet access to download packages and container images

Install Podman on Ubuntu

Podman is available directly from Ubuntu’s Universe repository, so no additional PPAs are required.

Step 1: Update Your Package Index

First, refresh the package list to ensure you are installing the latest available package from your configured repositories.

sudo apt update

Podman Install Howsnip

Step 2: Install Podman

Install Podman using APT:

sudo apt install podman

Podman Install Howsnip

This command downloads and installs Podman along with any required dependencies.

Step 3: Verify the Installation

Check whether Podman was installed successfully:

podman --version

Podman Install Howsnip

The output displays the installed Podman version. The exact version depends on your Ubuntu release.

Verify the Rootless Configuration

One of Podman’s biggest advantages is its ability to run containers without requiring root privileges.

Check Rootless Mode

Run:

podman info | head -20

Podman Install Howsnip

This command displays the first part of Podman’s configuration information.

Verify Subordinate UID and GID Mappings

Rootless containers rely on subordinate user and group ID mappings.

Check the configuration files:

cat /etc/subuid /etc/subgid

Podman Install Howsnip

Each user should have an assigned range of subordinate UIDs and GIDs that Podman uses internally for container isolation.

If Your User Entry Is Missing

Add subordinate IDs for your user:

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 howsnip

Then apply the changes:

podman system migrate

Important: Replace howsnip with your actual username.

Run Your First Podman Container

Let’s verify that Podman can pull and run containers successfully.

Start an Nginx Container

Run the following command:

podman run -d --name web -p 8081:80 nginx

Podman Install Howsnip

Verify the Container Is Running

List active containers:

podman ps

Podman Install Howsnip

You should see the web container in the output.

Test the Application

Send a request to the container:

curl -I http://localhost:8081

Podman Install Howsnip

A successful HTTP response confirms that traffic is reaching the Nginx server inside the container.

Remove the Container

When you’re finished testing:

podman rm -f web

Podman Install Howsnip

This command forcefully stops and removes the container.

Configure Container Registries

Podman searches configured registries when pulling container images without a registry prefix.

Open the Registry Configuration File

sudo nano /etc/containers/registries.conf

Podman Install Howsnip

Configure Search Registries

Add or update the following configuration:

unqualified-search-registries = [“docker.io”, “quay.io”]

This allows Podman to automatically search Docker Hub and Quay when image references don’t specify a registry.

For example:

podman pull alpine

can automatically resolve to:

docker.io/library/alpine:latest

Best Practice: Use fully qualified image references in scripts and CI/CD pipelines to avoid unexpected image sources.

Example:

podman pull docker.io/library/alpine

Use Podman as a Docker Replacement

If existing scripts or workflows use Docker commands, Podman can act as a drop-in replacement.

Install Docker Compatibility Support

sudo apt install podman-docker

Podman Install Howsnip

This package provides a Docker-compatible command that redirects requests to Podman.

Test Docker Compatibility

docker run --rm hello-world

Podman Install Howsnip

Although the command uses docker, Podman executes it behind the scenes. Most commonly used commands work the same way, including:

  • docker build
  • docker pull
  • docker push
  • docker images
  • docker ps
  • docker logs
  • docker exec

Build a Container Image with a Dockerfile

Podman can build OCI-compliant images using standard Dockerfiles.

Step 1: Create a Project Directory

mkdir hello-podman && cd hello-podman

Podman Install Howsnip

Step 2: Create the Flask Application

Create the application file:

nano app.py

Podman Install Howsnip

Add the following code:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
return "Hello from Podman!"

if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)

This simple Flask application returns a message when accessed in a browser.

Step 3: Create the Dockerfile

Create a file named Dockerfile and add:

FROM docker.io/library/python:3.12-slim

WORKDIR /app

RUN pip install --no-cache-dir flask

COPY app.py .

EXPOSE 5000

CMD ["python", "app.py"]

Podman Install Howsnip

Step 4: Build the Image

podman build -t hello-podman .

Podman Install Howsnip

A successful build tags the image as:

localhost/hello-podman:latest

Step 5: Run the Image

podman run -d --name hello -p 5000:5000 hello-podman

Podman Install Howsnip

Step 6: Test the Application

curl http://localhost:5000

Podman Install Howsnip

Expected output:

Hello from Podman!

Note: In rootless mode, images and containers are stored in the user’s home directory, typically under ~/.local/share/containers.

Create and Run a Pod

Podman supports Kubernetes-style pods that allow multiple containers to share networking and other resources.

Create a New Pod

podman pod create --name webapp -p 8082:80

This creates a pod named webapp and publishes port 8082.

Add a Redis Container

podman run -d --pod webapp --name redis redis:7

Podman Install Howsnip

Add an Nginx Container

podman run -d --pod webapp --name nginx nginx

Podman Install Howsnip

Because both containers share the same network namespace, they can communicate using localhost.

List Existing Pods

podman pod ps

Podman Install Howsnip

The output includes an additional infrastructure (infra) container that manages the shared pod resources.

Run Podman Containers as systemd Services

If you want containers to start automatically at login or boot, Podman’s Quadlet integration provides a clean systemd-based approach.

Step 1: Create the Quadlet Directory

mkdir -p ~/.config/containers/systemd

Step 2: Create a Container Definition

nano ~/.config/containers/systemd/web.container

Podman Install Howsnip

Add the following content:

[Unit]
Description=Rootless Nginx container

[Container]
Image=docker.io/library/nginx:latest
ContainerName=web
PublishPort=8082:80

[Service]
Restart=always

[Install]
WantedBy=default.target

This file defines how Podman should generate and manage the systemd service.

Step 3: Reload systemd

systemctl --user daemon-reload

This tells systemd to load the newly created configuration.

Step 4: Start the Service

systemctl --user start web.service

Step 5: Enable User Service Persistence

sudo loginctl enable-linger howsnip

Podman Install Howsnip

Important: Replace howsnip with your username.

Enabling lingering allows user services to continue running even after logout.

Quick Reference Commands

Install Podman
sudo apt install podman

Run a container
podman run -d –name web -p 8080:80 nginx

List containers
podman ps -a

Build an image
podman build -t myimage .

List images
podman images

Pull an image
podman pull alpine:latest

Remove a container
podman rm -f web

View Podman information
podman info

Conclusion

Podman provides a secure and lightweight alternative to Docker by eliminating the need for a privileged daemon and supporting rootless containers by default.

After installing Podman on Ubuntu, you can pull images, run containers, build applications from Dockerfiles, organize workloads into pods, and manage containers with systemd services. Because its command syntax closely matches Docker, transitioning existing workflows is typically straightforward while benefiting from improved security and flexibility.