Scan Images & Pin Digests

Scan images for known CVEs before you ship, and pin base images by immutable digest so a build today matches a build next year.

Two habits separate a hobby image from a production one: you know what vulnerabilities are inside it, and you can reproduce it byte-for-byte later.

Scan before you ship

Docker ships docker scout, and the ecosystem has excellent free scanners like Trivy and Grype. Wire one into CI and fail the build on fixable high/critical CVEs. Scanning a slim base regularly is what keeps you off the front page.

Pin by digest, not just by tag

A tag like node:20-alpine is a moving target — it points at a different image every few weeks. For reproducible, tamper-evident builds, pin the digest (@sha256:...). The tag can move; the digest never does.

ReferenceReproducible?Use for
node:latestNoNever in prod
node:20-alpineMostlyLocal / dev
node:20-alpine@sha256:…YesProduction builds

Update digests deliberately (a tool like Renovate or Dependabot can raise a PR), so upgrades are reviewed rather than silent.

Example

Example · bash
# Scan a built image with Docker Scout
docker scout cves myapp:1.0

# Or with Trivy (fail CI on fixable HIGH/CRITICAL)
trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 myapp:1.0

# Find the digest of a base image, then pin it in the Dockerfile
docker buildx imagetools inspect node:20-alpine
# FROM node:20-alpine@sha256:aa1b2c3...   <- paste the digest

When to use it

  • A CI pipeline runs trivy with --exit-code 1 on every built image to block deploys that introduce new CRITICAL vulnerabilities.
  • A team pins every FROM line to a SHA256 digest after scanning, so the image cannot silently change if the upstream tag is overwritten.
  • A security engineer schedules weekly registry scans with trivy to catch newly published CVEs in images already running in production.

More examples

Scan and gate on CRITICAL CVEs

Fails with exit code 1 if CRITICAL or HIGH unfixed vulnerabilities are found, blocking the CI pipeline.

Example · bash
trivy image \
  --exit-code 1 \
  --severity CRITICAL,HIGH \
  --ignore-unfixed \
  myapp:latest

Retrieve image digest for pinning

Retrieves the immutable SHA256 digest of the pulled image, ready to paste into a FROM line for digest pinning.

Example · bash
# Get the digest of a remote image
docker pull node:20-alpine
docker inspect node:20-alpine --format '{{index .RepoDigests 0}}'

Pin base image to digest

Locks the base image to an exact content-addressable digest so upstream tag updates cannot silently alter builds.

Example · dockerfile
# Tag can be overwritten; digest never changes
FROM node:20-alpine@sha256:a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
CMD ["node", "index.js"]

Discussion

  • Be the first to comment on this lesson.