PostgreSQL Container Image Build Pipeline#
The cloudnative-pg/postgres-containers repository contains the automated build pipeline for CloudNativePG's PostgreSQL operand images. It produces multi-arch (linux/amd64, linux/arm64) Docker images across multiple PostgreSQL major versions and Debian distributions, publishing them to ghcr.io/cloudnative-pg/postgresql.
Image Matrix#
Builds are defined in docker-bake.hcl, which drives Docker Bake. The matrix cross-products:
- PostgreSQL versions — currently 14–18 stable plus any preview (e.g.,
19~beta1) not yet promoted to stable - Debian bases —
trixie-slim,bookworm-slim,bullseye-slim, each pinned by SHA256 digest - Image types —
minimal,standard(adds pgaudit, pgvector, pg-failover-slots, Barman),system
Every image receives OCI provenance and SBOM attestations, and is tagged with both a rolling <major>-<type>-<distro> tag and a timestamped <version>-<YYYYMMDDhhmm>-<type>-<distro> tag .
Workflow Architecture#
Four GitHub Actions workflows orchestrate the pipeline:
| Workflow | Trigger | Purpose |
|---|---|---|
bake_update.yml | Mon 00:00 UTC (+ manual) | Updates postgreSQLVersions in docker-bake.hcl from the PostgreSQL versions API |
bake.yml | Mon 08:00 UTC, PR, manual | Matrix-builds all versions; dispatches catalog update after successful production runs |
bake_targets.yml | Called by bake.yml | Builds, scans, signs, and promotes images for one PostgreSQL major version |
catalogs.yml | repository_dispatch: update-catalogs, manual | Generates and signs ClusterImageCatalog YAMLs; commits to cloudnative-pg/artifacts |
The weekly cadence is intentionally staggered: version update runs at midnight, build bake runs eight hours later .
Renovate-Based Base Image Updates#
renovate.json configures Renovate Bot to track and auto-merge base image digest updates. Key behaviors:
- Digest pinning — all Debian base images in
docker-bake.hclare pinned by SHA256 digest via inline// renovate:comments ; Renovate detects upstream digest changes using a custom regex manager - Grouping — all Debian base image updates are grouped into a single PR
- Auto-merge — minor and digest updates are automatically merged without review
- Barman — the Barman Python package version is also tracked via a
datasource=pypiRenovate comment
⚠️ Known lag risk: Security packages in a new Debian release (e.g., trixie 13.5) are only picked up after Renovate detects and merges the new digest. The weekly build uses whatever digest is pinned at run time. If Renovate's polling misses the upstream release window before the Monday build, images ship with stale packages until the next cycle. This has caused critical CVEs to persist in published images.
Build & Promotion (bake_targets.yml)#
For each PostgreSQL major version, bake_targets.yml runs:
- Build — Docker Bake with
environment=testingpushes to the testing registry - Security scan —
.github/actions/security-scansruns Dockle and Snyk; Snyk usescontinue-on-error: trueso vulnerabilities are reported to GitHub Code Scanning without blocking promotion - Sign — Cosign signs images with keyless signing
- Promote —
.github/actions/copy-imagescopies from testing to production via Skopeo, then re-signs, when triggered onmainin production/schedule mode
The bake.yml matrix uses fail-fast: false , so a failure in one PostgreSQL version does not cancel other versions.
Catalog Generation#
After a successful production bake, bake.yml fires a repository_dispatch event . catalogs.yml then:
- Checks out both
postgres-containersandcloudnative-pg/artifacts - Runs
.github/actions/generate-catalogs, a Python action (catalogs_generator.py) that queriesghcr.io/cloudnative-pg/postgresql, applies a regex(\d+)(?:\.\d+|beta\d+|rc\d+|alpha\d+)-(\d{12})to find timestamped tags, picks the latest per major version, and emits oneClusterImageCatalogYAML per (distribution × image-type) - Signs each catalog YAML with Cosign
- Commits the results to
cloudnative-pg/artifacts/image-catalogs/
Monitoring & Failure Alerting#
There is no dedicated alerting workflow. The pipeline relies entirely on:
- GitHub's native notifications for workflow failures
- GitHub Code Scanning for Snyk vulnerability reports
- Community bug reports for catching gaps (e.g., builds silently succeeding with stale base image digests — see issue #10751)
Notably, even partial bake failures (one version failing) block catalog updates because the Catalogs job depends on the full Bake job completing . This means a single version's build failure suppresses catalog refreshes for all successfully built versions.