Safeguard
Tools

Best Container Base Images for Security in 2026

Chainguard, distroless, Alpine, UBI micro, Ubuntu chiseled, and scratch, compared on CVE counts, size, libc, and the operational costs nobody puts in the marketing.

Elena Kovacs
Compliance Architect
7 min read

The most secure container base images in 2026 are minimal, shell-free images with an active patch pipeline: Chainguard Images and Google's distroless lead, Ubuntu chiseled and Red Hat UBI micro are the enterprise-friendly middle, and Alpine remains the pragmatic choice when you need a shell and can live with musl. Base image choice is the highest-leverage container security decision you make, because it sets the floor for every scan result, every patch cycle, and every 3 a.m. debugging session for the life of the service.

The numbers below come from scanning each image with Trivy 0.62 in late May 2026. Your counts will drift with the date; the relative ordering has been stable for two years.

The comparison table

ImageSizeShellPackage managerlibcCVEs (H/C) at scan
cgr.dev/chainguard/static2 MBnonon/a0
gcr.io/distroless/static-debian122 MBnonon/a0
cgr.dev/chainguard/wolfi-base13 MByesapkglibc0
gcr.io/distroless/base-debian1220 MBnonoglibc1
ubuntu:24.04 (chiseled runtime)12 MBnonoglibc0
registry.access.redhat.com/ubi9-micro24 MBnonoglibc2
alpine:3.228 MByesapkmusl0
debian:trixie-slim75 MByesaptglibc9
scratch0nonon/a0

Zero-CVE claims deserve one caveat up front: a zero on scan day measures patch velocity, not invulnerability. The question is what the count looks like 45 days after you stop rebuilding.

Chainguard: zero-CVE as an SLA, priced accordingly

Chainguard Images, built on the Wolfi undistro, made "zero known CVEs" a contractual promise rather than a snapshot, with glibc compatibility so you avoid musl surprises. Every image ships with a signed SBOM and provenance attestations verifiable with cosign — the workflow we walk through in cosign verification policies in production:

cosign verify cgr.dev/chainguard/nginx \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  --certificate-identity-regexp='https://github.com/chainguard-images/.*'

The catch is commercial: the free tier only includes latest and latest-dev tags. Pinning to a specific version — which you want for reproducibility — requires a paid plan, and pricing lands in procurement territory. Teams that budget for it stop arguing with scanners; teams that do not should look at the next three options.

Distroless: the free workhorse

Google's distroless images remain what most teams should reach for by default. Debian-based, no shell, no package manager, four variants that cover most runtimes: static (fully static binaries), base (glibc + CA certs + tzdata), cc (adds libgcc), and language images for Java, Python, and Node.

The multi-stage pattern is unchanged and still right:

FROM golang:1.24 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./cmd/server

FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /app /app
ENTRYPOINT ["/app"]

Use the :nonroot tag; a surprising number of distroless deployments still run as UID 0 for no reason anyone can recall. Weakness: patch cadence follows Debian point releases, so a CVE in glibc can sit visible-but-unfixed in scanners for longer than Chainguard or Ubuntu would take.

Ubuntu chiseled and UBI micro: minimal for the enterprise

Ubuntu's chiseled images take the Debian-family packages and carve them into "slices," producing shell-less runtime images backed by Canonical's CVE patching and available with FIPS-certified crypto under Ubuntu Pro. For .NET and Java shops already on Ubuntu, chiseled is the lowest-friction road to a minimal runtime — Microsoft publishes chiseled .NET images directly.

Red Hat UBI micro is the equivalent answer inside the Red Hat world: freely redistributable, no package manager in the image (you install packages at build time with dnf --installroot on the build host), and CVE response backed by Red Hat errata. Choose it when your customers ask "is the base OS vendor-supported" in security questionnaires — the honest answer matters more than the CVE count for regulated buyers. It carried two moderate-severity CVEs at scan time, both with published errata dates.

Alpine and scratch: the classics, with asterisks

Alpine at 8 MB with a real shell and apk is still the best debugging-friendly minimal image. Its two structural costs are unchanged: musl libc (DNS behavior differences and occasional performance cliffs in threaded workloads — Python data stacks compiled against glibc wheels suffer most) and a security team much smaller than Debian's or Canonical's. For Go and Rust services, those costs round to zero. For Python and JVM, measure before committing.

scratch is the theoretical optimum and correct for fully static binaries that need no CA bundle or timezone data — but the moment you need TLS to external services you are copying in ca-certificates yourself, at which point distroless/static or chainguard/static does the same thing with a maintained update path.

Special mention: Docker Hardened Images, launched in 2025, follow the Chainguard playbook (minimal, attested, patched) inside Docker Hub's distribution. Worth evaluating if you are already paying Docker, though the catalog is younger.

The operational half of the decision

Whatever you pick, the image is only as secure as its rebuild cadence. Three practices matter more than the logo on the base layer:

  • Rebuild on a schedule, not on release. Weekly rebuilds pick up base patches even when your code has not changed. A perfect base image pinned for six months is a bad base image.
  • Pin by digest, update by automation. FROM alpine@sha256:... plus Renovate or Dependabot bumping the digest gives you reproducibility and freshness.
  • Scan the final image, not the base. Your application layers reintroduce OS packages and vendored libraries; scanning distroless/static and calling it done misses everything you copied in. Continuous scanning of built images against new advisories — the job platforms like Safeguard automate alongside SBOM management — is what catches the CVE published three weeks after you shipped.

Debugging on shell-less images stopped being a valid objection in 2023: kubectl debug --image=busybox --target=app attaches an ephemeral container with tools, no shell in the production image required.

Frequently asked questions

Are zero-CVE base images worth paying for?

If your team spends meaningful hours triaging base-image findings or your customers contractually require clean scans, yes — the subscription is cheaper than the toil. If your scanner noise is dominated by application dependencies rather than OS packages, fix that first; a paid base image will not move your real risk much.

Is Alpine still safe to use in 2026?

Yes, with eyes open. Its CVE record is good and its size is real, but musl compatibility issues are a correctness risk, and its smaller security team means occasionally slower advisory response than Debian, Canonical, or Red Hat. It is the right default for static-friendly languages and the wrong one for glibc-assuming Python wheels.

How do I patch a distroless or shell-less image?

You do not patch it in place — you rebuild from an updated base and redeploy, which is why rebuild cadence is the actual control. Digest-pinned bases updated by Renovate, plus weekly scheduled rebuilds, keep the window between upstream patch and your redeploy under seven days without human involvement.

Should Windows containers follow the same guidance?

Directionally yes: prefer Nano Server over Server Core for the same minimal-surface reasons, and rebuild monthly with patch Tuesday. The zero-CVE ecosystem (Chainguard, distroless) is Linux-only, so scanning and rebuild cadence carry even more of the weight on Windows.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.