A Podman-powered CI build image preloaded with essential container tools: Buildah, Crane, Cosign, Manifest Tool, ORAS, Make, JQ, Bash, and Vault.
- Based on alpine image
- Pre-installed tools for container image management and CI/CD workflows
- Multi-architecture support (amd64 and arm64)
You can pull the image from either GitHub Container Registry or Docker Hub:
# Pull the latest version
docker pull ghcr.io/pjaudiomv/podman-ci-toolkit:latest
# Or pull a specific version by tag
docker pull ghcr.io/pjaudiomv/podman-ci-toolkit:1.0.0
# Pull the latest version
docker pull pjaudiomv/podman-ci-toolkit:latest
# Or pull a specific version by tag
docker pull pjaudiomv/podman-ci-toolkit:1.0.0
# Run the container with interactive shell (GitHub Container Registry)
docker run --rm -it ghcr.io/pjaudiomv/podman-ci-toolkit:latest /bin/bash
# Or using Docker Hub
docker run --rm -it pjaudiomv/podman-ci-toolkit:latest /bin/bash
# Mount your local directory to build a container
docker run --rm -it \
-v $(pwd):/workspace \
-w /workspace \
podman-ci-toolkit:test \
podman build --file=hello.Dockerfile --build-context build=/workspace --tag=your-image:latest
jobs:
build:
runs-on: ubuntu-latest
container:
# Use either GitHub Container Registry
image: ghcr.io/pjaudiomv/podman-ci-toolkit:latest
# Or Docker Hub
# image: pjaudiomv/podman-ci-toolkit:latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build and push with Podman
run: |
podman build \
--file=Dockerfile \
--build-context build=$(pwd) \
--tag ghcr.io/username/repo:latest
The image includes the following tools:
- Podman - Podman: A tool for managing OCI containers and pods.
- Crane - Tool for interacting with remote container registries
- Cosign - Container signing, verification, and storage in an OCI registry
- Manifest Tool - Tool for creating and pushing manifest lists for multi-architecture images
- ORAS - OCI Registry As Storage for artifacts
- Make - Build automation tool
- JQ - Lightweight and flexible command-line JSON processor
- Bash - GNU Bourne Again SHell
- Vault - Tool for secrets management, encryption as a service, and privileged access management
This project uses GitHub Actions for continuous integration and delivery:
-
Test Build Workflow - Runs on pull requests to verify that the Dockerfile builds successfully:
- Performs multi-architecture builds (amd64, arm64)
- Runs basic tests to verify tool functionality
- Ensures changes don't break the build process
-
Build and Push Workflow - Runs on pushes to main branch and tags:
- Builds multi-architecture images
- Pushes to both GitHub Container Registry and Docker Hub
- Creates proper tags for versioning
The repository includes an example GitHub workflow (.github/workflows/example.yaml
) that demonstrates how to use the podman-ci-toolkit image in a real-world CI/CD pipeline:
name: Example Multi-Arch Podman Build
on:
push:
tags: ['v*']
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.set-tag.outputs.tag }}
steps:
- name: Determine tag
id: set-tag
run: |
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
echo "tag=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT
elif [[ "${GITHUB_REF_NAME}" == "${{ github.event.repository.default_branch }}" ]]; then
echo "tag=latest" >> $GITHUB_OUTPUT
else
echo "tag=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
fi
build:
needs: prepare
strategy:
matrix:
include:
- os: ubuntu-24.04
arch: amd64
- os: ubuntu-24.04-arm
arch: arm64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup docker auth config
run: |
mkdir -p .docker
echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"$(echo -n "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" | base64)\"}}}" > .docker/config.json
- name: Build and push ${{ matrix.arch }} image
run: |
docker run --rm \
-v "$PWD:/workspace" \
-v "$PWD/.docker:/home/builder/.docker" \
-w /workspace \
ghcr.io/pjaudiomv/podman-ci-toolkit:1.0.0 \
podman build \
--file /workspace/hello.Dockerfile \
--build-context build=/workspace \
--tag "docker.io/pjaudiomv/hello-test:${{ needs.prepare.outputs.tag }}-${{ matrix.arch }}"
manifest:
name: Create Multi-Arch Manifest
runs-on: ubuntu-latest
needs: [prepare, build]
steps:
- name: Setup docker auth config
run: |
mkdir -p .docker
echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"$(echo -n "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" | base64)\"}}}" > .docker/config.json
- name: Push Multi-Arch Manifest
run: |
docker run --rm \
-v "$PWD:/workspace" \
-v "$PWD/.docker:/home/builder/.docker" \
-w /workspace \
ghcr.io/pjaudiomv/podman-ci-toolkit:1.0.0 \
manifest-tool push from-args \
--platforms linux/amd64,linux/arm64 \
--template "docker.io/pjaudiomv/hello-test:${{ needs.prepare.outputs.tag }}-ARCH" \
--target "docker.io/pjaudiomv/hello-test:${{ needs.prepare.outputs.tag }}"
This workflow demonstrates:
- Dynamic Tag Generation: Automatically determines the appropriate tag based on the Git reference
- Multi-Architecture Builds: Builds images for both amd64 and arm64 architectures
- Docker Registry Authentication: Sets up authentication for Docker Hub
- Podman Image Building: Uses the podman-ci-toolkit to build and push architecture-specific images
- Multi-Architecture Manifest: Creates and pushes a multi-architecture manifest using manifest-tool
You can use this workflow as a template for your own projects, adjusting the Dockerfile path, destination registry, and other parameters as needed.
Here's an equivalent example for GitLab CI (.gitlab-ci.yml
):
stages:
- prepare
- build
- manifest
variables:
DOCKER_REGISTRY: docker.io
DOCKER_IMAGE: pjaudiomv/nginx-test
prepare:
stage: prepare
image: ghcr.io/pjaudiomv/podman-ci-toolkit:1.0.0
script:
- |
if [[ -n "$CI_COMMIT_TAG" ]]; then
echo "TAG=$CI_COMMIT_TAG" >> variables.env
elif [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
echo "TAG=latest" >> variables.env
else
echo "TAG=${CI_COMMIT_SHA:0:7}" >> variables.env
fi
artifacts:
reports:
dotenv: variables.env
.build-template: &build-template
stage: build
needs:
- prepare
script:
- mkdir -p .docker
- echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"$(echo -n "${DOCKERHUB_USERNAME}:${DOCKERHUB_TOKEN}" | base64)\"}}}" > .docker/config.json
- |
podman build \
--file /nginx.Dockerfile \
--build-context / \
--tag "$DOCKER_REGISTRY/$DOCKER_IMAGE:$TAG-$ARCH"
build-amd64:
<<: *build-template
variables:
ARCH: amd64
tags:
- amd64
build-arm64:
<<: *build-template
variables:
ARCH: arm64
tags:
- arm64
manifest:
stage: manifest
needs:
- prepare
- build-amd64
- build-arm64
script:
- mkdir -p .docker
- echo "{\"auths\":{\"https://index.docker.io/v1/\":{\"auth\":\"$(echo -n "${DOCKERHUB_USERNAME}:${DOCKERHUB_TOKEN}" | base64)\"}}}" > .docker/config.json
- |
manifest-tool push from-args \
--platforms linux/amd64,linux/arm64 \
--template "$DOCKER_REGISTRY/$DOCKER_IMAGE:$TAG-ARCH" \
--target "$DOCKER_REGISTRY/$DOCKER_IMAGE:$TAG"
only:
- tags
# Only run the pipeline for tags starting with 'v'
workflow:
rules:
- if: $CI_COMMIT_TAG =~ /^v.*/
This GitLab CI configuration achieves the same functionality as the GitHub workflow:
- Dynamic Tag Generation: Uses GitLab CI variables to determine the appropriate tag
- Multi-Architecture Builds: Uses GitLab runners with specific tags for different architectures
- Docker Registry Authentication: Sets up authentication using GitLab CI variables
- Podman Image Building: Uses the podman-ci-toolkit to build and push architecture-specific images
- Multi-Architecture Manifest: Creates and pushes a multi-architecture manifest
Note that you'll need to:
- Set up GitLab CI variables for
DOCKERHUB_USERNAME
andDOCKERHUB_TOKEN
- Configure GitLab runners with the appropriate architecture tags (
amd64
andarm64
)
Contributions are welcome! Please feel free to submit a Pull Request.
This project is distributed under the MIT License. See the LICENSE file for more information.