Is the Postgres Docker Image Safe? What Our Scanner Found
Published July 8, 2026 · 6 min read
Postgres is one of the most-deployed database images on Docker Hub, so “is the postgres Docker image safe” is worth answering with data instead of assumptions. We scanned postgres:17 and its Alpine variant with ScanRook and looked at what the findings actually mean.

The verdict
Mostly yes, with caveats. The Postgres project ships timely fixes for the database engine itself, and CVEs in Postgres proper are relatively rare compared to the finding count you see on a full scan. The bulk of that count comes from the Debian base image underneath — GnuPG, dirmngr, and the rest of the userland required to verify and install packages during the build. The practical risks are running an oversized tag when a slimmer one would do, skipping rebuilds after base image patches ship, and giving the database container more privilege than it needs. All three are addressable without touching your schema.
What we found scanning postgres:17
We exported the image with docker save and scanned it with ScanRook, which matches every installed package against OSV, NVD, and vendor advisory data. Here is the severity breakdown for the default Debian-based tag and the Alpine variant:
| Tag | Total | Critical | High | Medium | Low |
|---|---|---|---|---|---|
| postgres:17 | 2,983 | 387 | 970 | 1,344 | 241 |
| postgres:17-alpine | 410 | 36 | 194 | 168 | 9 |
ScanRook v1.14.2, warm-cache scan, 2026-07-04. Counts change as new advisories publish.
As with most Debian-based official images, the headline number is dominated by the base operating system rather than the application. postgres:17 ships GnuPG and its dirmngr helper for signature verification, plus a broad set of Debian utilities, and each contributes its own advisory history. The Alpine tag strips almost all of that away, which is why it carries roughly 86% fewer findings.
The CVEs worth knowing about
The top critical findings from our scan of postgres:17 cluster around three packages:
- dirmngr — CVE-2005-2023 and CVE-2006-6235.dirmngr is GnuPG's network-facing helper for fetching keys and checking certificate revocation. Both advisories date to the mid-2000s. dirmngr only runs when Postgres's package manager needs to verify a signature, which in a running database container is effectively never — it matters at build time, not at query time.
- gnupg — CVE-2005-2023 and CVE-2006-6235.Same advisories, flagged against the core GnuPG binary that dirmngr depends on. It ships in the image because Debian's package tooling uses it to verify APT repository signatures during builds and rebuilds.
- gnupg-l10n — CVE-2005-2023.The localization data package for GnuPG. It carries the same advisory as its parent binary but contains no executable code of its own — it is translation strings, not attack surface.
None of these touch the Postgres server process itself. They are a byproduct of Debian's package-verification chain being present in the image. Our guide to installed-state scanning vs. advisory matching covers why scanners flag decades-old build tooling like this at all.
Which tag should you use?
For most deployments, postgres:17-alpine is the better default. Same upstream Postgres release, same initialization scripts and environment variables, but 410 findings instead of 2,983 and 36 critical instead of 387 in our scan. The tradeoff is musl libc instead of glibc, which occasionally affects extensions compiled against glibc-specific behavior.
Stay on the Debian-based tag if you depend on extensions distributed only as glibc binaries, or your organization standardizes on Debian for compliance tooling. Either way, pin an exact version rather than tracking a floating tag. For the broader tradeoffs between base image families, see Alpine vs Debian vs Distroless.
Hardening checklist
- Run the container as the built-in non-root
postgresuser rather than overriding it to root. - Pin the image by digest (
postgres@sha256:…), not just by tag, so restores and redeploys are reproducible. - Store credentials via
POSTGRES_PASSWORD_FILEor a secrets manager instead of plain environment variables. - Mount the data directory on a dedicated volume with restrictive host permissions.
- Restrict network exposure — bind to an internal network and avoid publishing 5432 publicly.
- Rebuild and redeploy on a schedule so base image patches actually reach your running containers.
- Scan every build in CI so a base image regression is caught before it ships.
Scan it yourself
Counts drift as new advisories publish, so verify against the exact tag and digest you deploy:
curl -fsSL https://scanrook.io/install.sh | sh docker save postgres:17 -o postgres.tar scanrook scan postgres.tar
The full CLI reference, including JSON output and severity gating for CI, is in the docs.
Frequently asked questions
Is the postgres Docker image safe to use?
Broadly yes. Postgres itself is patched quickly; most findings come from the Debian base packages underneath it. Use the Alpine tag, pin versions, and rebuild regularly to address the bulk of the practical risk.
Why does the image have so many vulnerabilities?
The default tag ships GnuPG, dirmngr, and a full Debian userland for package verification. Scanners report the whole operating system layer, not just the Postgres binaries.
Is postgres:alpine more secure?
It has a much smaller attack surface: 410 findings vs 2,983 in our scan, about 86% fewer, because musl libc and BusyBox replace the full Debian userland.
Do I need to fix every reported CVE?
No. Triage by severity and reachability — GnuPG and dirmngr never execute in a running Postgres container. A smaller base tag removes whole categories of findings at once.
Scan your postgres image with ScanRook
Upload your image tar or scan from the CLI and ScanRook matches every installed package against OSV, NVD, and vendor advisory data — with severity, exploit-probability, and confidence tiers so you can separate real runtime risk from build-time noise.