Podman Container Management: Rootless Containers and Pods

You’re on a shared server or a locked-down CI runner, you need to run a few containers, and nobody is going to give you root or let you install the Docker daemon. That’s exactly where Podman shines. This post shows you the basics of Podman container management: running rootless containers, grouping them in pods, switching over from Docker, and using Podman in your CI/CD pipeline.

What Podman is

Podman is an open-source command-line tool for building, running, and managing containers. If you’ve used Docker, you already know most of it, because the commands are nearly the same. The big difference is that Podman has no background daemon, and it can run containers as a normal user.

To install it on Ubuntu or Debian, run:

sudo apt install podman

On Fedora, RHEL, or similar distros, run:

sudo dnf install podman

Then check that it works:

podman --version

If you see a version number, you’re ready to go.

Run rootless containers

A rootless container is a container you start as a regular user, without sudo or root privileges. Podman does this out of the box, and it’s the main reason I’d suggest it for security-minded setups: if something breaks out of the container, it lands in your user account, not as root on the host.

To check that you’re running rootless, run:

podman info --format '{{.Host.Security.Rootless}}'

It should print true. Now start a web server, no sudo needed:

podman run -d --name web -p 8080:80 docker.io/library/nginx:alpine

Open http://localhost:8080 and you should see the nginx welcome page. One thing to know: as a normal user you can’t bind ports below 1024 by default, which is why I mapped to 8080 instead of 80.

To list your running containers, run:

podman ps

Picture a developer who wants to ship a containerized app without handing out root on the build box. With Podman, they start containers with a single command and never touch sudo.

Group containers in a pod

A Podman pod is a group of containers that share the same network, so they can talk to each other over localhost. The idea comes straight from Kubernetes, and it’s handy when your app is a frontend, a backend, and a database that always run together.

To create a pod and publish its port, run:

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

Ports are set on the pod, not on each container. Next, add a database to the pod:

podman run -d --pod myapp --name db -e POSTGRES_PASSWORD=changeme docker.io/library/postgres:16

Then add the web container:

podman run -d --pod myapp --name app docker.io/library/nginx:alpine

The app container can now reach Postgres at localhost:5432. To see your pods, run:

podman pod ps

Here’s a nice bonus. You can turn the pod into a Kubernetes YAML file:

podman kube generate myapp > myapp.yaml

On older Podman versions the command is podman generate kube. You can recreate the whole pod from that file later with podman kube play myapp.yaml, or take it to a real cluster. If you go that route, these Kubernetes CLI tools for managing clusters faster will help.

Podman vs Docker: what changes

The short answer: for daily use, very little. Podman uses the same image format and pulls from the same registries, and most Docker commands work if you just swap the word docker for podman.

The quick way to switch is an alias. Add this to your ~/.bashrc or ~/.zshrc:

alias docker=podman

Reload your shell and your old muscle memory keeps working. The manual way, typing podman every time, is better in scripts you share with others, so nobody gets confused about which tool is really running.

The real differences are under the hood:

  • No daemon: each container runs as a child process of your command, so there’s no always-on service to manage.
  • Rootless by default: Docker can run rootless too, but it takes extra setup.
  • Pods built in: Docker has no native pod concept.

If your project leans heavily on Docker Compose, like the setup in my Grafana with Docker Compose guide, test it carefully before switching.

Use Podman in CI/CD

Podman fits CI/CD pipelines well because it’s just a CLI with no daemon to start, and it doesn’t need root on the runner. That makes it a good choice for shared runners where you can’t, or shouldn’t, have root access.

To log in to your registry, run:

podman login registry.example.com

To build and tag your image, run:

podman build -t registry.example.com/user/repo:latest .

Then push it:

podman push registry.example.com/user/repo:latest

Swap in your own registry and user/repo. In a real pipeline, put these three commands in your build step and pass the registry password through a CI secret, never in plain text. Once the image is pushed, a tool like Ansible can roll it out; my post on Nginx deployment with Ansible is a good starting point.

Should you switch to Podman?

If security matters to you, or you work on machines where you don’t have root, I’d give Podman a serious try. Start with the alias, run your usual containers for a week, and see what breaks. For most projects the answer is: not much.

Hope this saves you some time, and happy containering! 🐳

Frequently asked questions

Can Podman use images from Docker Hub?

Yes. Podman uses the standard OCI image format, so it can pull images from Docker Hub and other registries. Use the full name, like docker.io/library/nginx, so Podman knows exactly where to look.

Does Podman work with Docker Compose files?

It can, through tools like podman-compose or Podman's Docker-compatible API. Simple Compose files usually work, but more complex setups may need tweaks. Test your project before you switch for good.

Why can't my rootless container use port 80?

By default, Linux doesn't let regular users bind ports below 1024. Map the container to a higher port like 8080, or put a reverse proxy in front. Changing the system setting is possible but affects the whole host.


Leave a Reply