Container Image Scanning
Tiffin's app.py is 2,000 lines, but its container image holds a whole operating system: a shell, package managers, compression libraries, maybe a compiler. Each of those packages can have known vulnerabilities, and they ship to production alongside the code you actually wrote. Image scanning shows what you are really shipping.
The rule
Ship less, pin what you ship, scan it twice, rebuild often.
An image scanner (Trivy and Grype are common open-source ones) lists every OS package and language library inside an image and matches them against vulnerability databases. Each finding has a severity and often a fixed-in version.
- Ship less. A full base image can carry hundreds of packages the app never touches. A
slim, Alpine or distroless base removes most of them, and every removed package is a vulnerability you never have to triage. Multi-stage builds keep compilers in the build stage only. - Pin what you ship. A tag like
python:3.12can point to different images tomorrow. Pinning by digest makes builds repeatable:
FROM python:3.12@sha256:<digest> AS build
COPY requirements.lock .
RUN pip install --prefix=/install -r requirements.lock
FROM python:3.12-slim@sha256:<digest> AS runtime
COPY --from=build /install /usr/local
COPY app/ /app
USER 10001- Scan it twice. Scan in the pipeline before pushing, and let the registry rescan stored images, because new vulnerabilities are published every day for images that have not changed.
- Rebuild often. Patches arrive in base images. A scheduled rebuild, say weekly, pulls them in even when the app code has not changed.
The shortcut
Triage findings in this order: fixable and severe → remove what you don't need → decide on the rest.
The report
Full
python:3.12base: 212 findings, 3 critical, 40 high.
A zero count is not the goal; a known, shrinking, justified list is.
Drills
Answer fast — trust the rule.
Why does switching to a slim or distroless base image reduce vulnerability findings?
What does pinning FROM python:3.12-slim@sha256:... achieve?
An image passed its scan three months ago and has not changed. Why can it now fail?
Which finding should be fixed first?
Remember
- Ship less, pin what you ship, scan it twice, rebuild often.
- Triage: fixable and severe → remove what you don't need → decide on the rest.
- A clean scan today is not a clean scan next month.
