Podman in CI/CD is less about building containers and more about building secure, reproducible pipelines that are easier to manage than Docker.

Let’s see it in action. Imagine a simple Node.js application with a test suite.

# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Podman
        uses: redhat-actions/podman-installer@v1

      - name: Build container image
        run: |
          podman build -t my-app:latest .

      - name: Run tests in container
        run: |
          podman run --rm my-app:latest npm test

This GitHub Actions workflow demonstrates a basic pipeline. It checks out the code, installs Podman, builds an image named my-app from the current directory, and then runs the npm test command inside a temporary container created from that image. The --rm flag ensures the container is automatically removed after the test.

The core problem Podman solves in CI/CD is the daemon dependency and root privilege requirements that often plague Docker. Traditional Docker setups in CI environments typically involve running the Docker daemon, which requires elevated privileges and can be a security concern. Podman, designed to run as a non-root user and without a central daemon, offers a more secure and flexible alternative. It integrates seamlessly into CI/CD tools like GitHub Actions, GitLab CI, and Jenkins, often requiring only a simple setup step to install the Podman binaries.

Internally, Podman uses a fork/exec model. When you run a podman build or podman run command, Podman directly interacts with the kernel’s container primitives (namespaces, cgroups) and a container registry. There’s no long-running daemon to manage or secure. For image building, it uses Buildah under the hood. For running containers, it leverages runc or crun. This architecture means that each Podman command is an independent process, making it more resilient and easier to integrate into isolated CI/CD job environments.

The exact levers you control are the container runtime itself and its configuration. You can specify different storage drivers (though for CI, the default overlayfs is usually fine), network configurations (though for build/test, often no complex networking is needed), and security profiles (like SELinux or AppArmor, though these are less critical in ephemeral CI environments). The key is that Podman’s user-centric design means you can often run these commands directly within the CI job’s user context without needing sudo or special daemon configurations, simplifying the CI pipeline setup significantly.

Many users assume that because Podman doesn’t have a daemon, it cannot manage images or containers effectively in a CI context. However, Podman’s design allows it to maintain its own local storage for images and container configurations, typically under ~/.local/share/containers/storage, without needing a central daemon. This decentralized storage means that even in an ephemeral CI runner, Podman can pull images, build new ones, and run containers, with all state managed locally to the user running the command.

The next step in mastering Podman in CI/CD is exploring its integration with Kubernetes for deployment, specifically using Podman to build images that can then be pushed to a registry and deployed to a cluster.

Want structured learning?

Take the full Podman course →