fyannkfyannk/postgres

Secured PostgreSQL images

The official PostgreSQL image, kept as close to zero known, fixable vulnerabilities as it can be, and measured in the open. Every night, each image is scanned next to its official counterpart with two scanners, and this page shows the result, including what is left.

An independent, personal project, not affiliated with, endorsed by or sponsored by the PostgreSQL project, docker-library, Docker, or any company.

Loading the latest scan…

How the images stay patched

Most findings in a container image are not in PostgreSQL. They are in the distribution packages around it and in anything bundled on top. Four things keep them down here.

  • Rebuilt when a fix lands. An image is rebuilt whenever upstream's recipe or the Debian or Alpine base image changes, and at least once a week regardless, so distribution security updates reach it without waiting for the next release.
  • Nothing bundled that the distribution cannot patch. The official image downloads gosu, a Go program, only to drop from root to postgres at startup. It carries the Go standard library it was compiled with, so every Go advisory published since stays in the image until gosu is rebuilt, and distribution updates cannot reach it. Here the same step is done by setpriv, part of the distribution's util-linux and patched like the rest. It is the only change made to upstream's recipe.
  • Checked before it ships. Every change is built, started and scanned before it is merged, and one that introduces a critical finding with an available fix is blocked.
  • Measured, not claimed. Each published image comes with its SBOM, and the comparison below is regenerated every night from public data, with every remaining finding listed.

The Dockerfile, entrypoint, environment variables, init scripts and tags are otherwise upstream's, so switching is a matter of changing the registry prefix:

docker pull ghcr.io/fyannk/postgres:18

Latest stable

The newest stable PostgreSQL release, ours next to the official image, on each base.

Scanner

Over time

One point per nightly scan.

    Show as a table

    Every image

    Every version and base built here, each scanned by both scanners, next to the official image.

    Tags

    What each tag points to, as of the last scan. The same tags exist on ghcr.io/fyannk/postgres and docker.io/fyannk/postgres, and resolve to the same digest.

    How this is measured

    • Same inventory tool on both sides. Each image we publish carries an SPDX SBOM produced by Syft at build time. For upstream's image, Syft is run on the official image each night, pulled through mirror.gcr.io, Google's mirror of Docker Hub, which serves the same digests. Only linux/amd64 is compared, the platform published here.
    • Two scanners. grype scans those SBOMs, including the Go standard library compiled into any Go binary (grype's default skips that). Trivy scans the images themselves. They use different vulnerability databases and severity sources, so their counts differ; the gap between ours and upstream is what to compare. The build time of each scanner's advisory database is shown at the top of the page, and flagged when it is more than two days older than the scan.
    • "With a fix" means a fixed version of the affected package exists. Those are the findings a rebuild can clear. The rest are waiting on Debian, Alpine or upstream projects, for ours and upstream alike.
    • Same version, same base. Each row compares the same PostgreSQL release on the same Debian or Alpine release. The two images are built at different times, so distribution package versions can differ slightly between them.
    • Counts are one per advisory and package, per image. Nothing is summed across images: an advisory present in five images is five findings, so a total would mostly measure how many images there are.

    The raw data is public: latest summary, history, and, for each image, every finding and the SBOM of the published image, linked from the tags table above.