What is Trivy?

Straight off the Trivy website https://trivy.dev/latest/ , Trivy is used to find vulnerabilities (CVE) & configurations (IaC) across code repositories, binary artifacts, container images, Kubernetes clusters, and more!

What is a CVE?

Great question! First of all CVE is short for Common Vulnerabilities and Exposures. It is a list of publicly disclosed computer security flaws. Each CVE is issued an ID, and in short CVEs help IT professionals coordinate their efforts to prioritize and addressed these vulnerabilities to make computer systems as secure as possible

Getting started with Trivy

I will be using Trivy to scan container images for CVEs. Trivy is a command-line application. What trivy will do is pull in a database of CVEs and scan my container images against the database, and tell me everything wrong with my image

The container image that I will be scanning is quite large. Generally speaking the larger the image, the larger the attack surface, and as a result the more CVE vulnerabilities.

docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
backend      00        e48cc776d20c   31 minutes ago   1.09GB
 

To scan my container image I will use the following command

TAG=00 && trivy image --format table --severity CRITICAL,HIGH backend:$TAG

Trivy will scan my container image and the out out will be in the form of a table below is a snippet of the scan result

Total: 146 (HIGH: 141, CRITICAL: 5)
 
┌───────────────────┬────────────────┬──────────┬──────────────┬─────────────────────────┬───────────────┬──────────────────────────────────────────────────────────────┐
      Library Vulnerability Severity    Status    Installed Version Fixed Version                            Title
├───────────────────┼────────────────┼──────────┼──────────────┼─────────────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
 icu-devtools CVE-2025-5222 HIGH affected 72.1-3 icu: Stack buffer overflow in the SRBRoot::addTag function
 https://avd.aquasec.com/nvd/cve-2025-5222
├───────────────────┼────────────────┼──────────┤              ├─────────────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
 libaom3 CVE-2023-6879 CRITICAL 3.6.0-1+deb12u1 aom: heap-buffer-overflow on frame size change
 https://avd.aquasec.com/nvd/cve-2023-6879
                   ├────────────────┼──────────┼──────────────┤                         ├───────────────┼──────────────────────────────────────────────────────────────┤
 CVE-2023-39616 HIGH will_not_fix AOMedia v3.0.0 to v3.5.0 was discovered to contain an
 invalid read mem...
 https://avd.aquasec.com/nvd/cve-2023-39616
├───────────────────┼────────────────┤          ├──────────────┼─────────────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
 libbluetooth-dev CVE-2023-44431 fix_deferred 5.66-1+deb12u2 bluez: AVRCP stack-based buffer overflow remote code
 execution vulnerability
 https://avd.aquasec.com/nvd/cve-2023-44431
                   ├────────────────┤                       

To recall my current docker image size is over 1GB in size

docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED             SIZE
backend      00        e48cc776d20c   About an hour ago   1.09GB

My current Dockerfile is as follows

 
FROM python:latest
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
 
WORKDIR /app
 
COPY . /app
 
RUN uv sync --locked --no-editable
 
CMD ["uv", "run", "study-tracker-api"]
 

As of now my Docker image is huge in size and full of CVEs. The current base image of my Dockerfile is FROM python:latest this image contains an almost entire Operating Systems and tons of packages that I do not need. The easiet and quickest way to reduce image size is to use a different base image python:3.13-slim

 
# FROM python:latest
FROM python:3.13-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
 
WORKDIR /app
 
COPY . /app
 
RUN uv sync --locked --no-editable
 
CMD ["uv", "run", "study-tracker-api"]
 

With this one change I have reduced the image size by 800MB

docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
backend      01        ae9b526becd0   13 seconds ago   189MB
backend      00        e48cc776d20c   2 hours ago      1.09GB

Now that was simple. A best practice is to always use alpine images. What is alpine? Alpine linux is a security-oriented, lightweight Linux distribution. To further slim down my container image I will use the python:3.13-alpine image

 
#FROM python:latest
#FROM python:3.13-slim
FROM python:3.13-alpine
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
 
WORKDIR /app
 
COPY . /app
 
RUN uv sync --locked --no-editable
 
CMD ["uv", "run", "study-tracker-api"]

Rebuilding my container image with the alpine image further reduced the size of my container over 70MB

docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
backend      02        a381a5f768d1   3 seconds ago    114MB
backend      01        ae9b526becd0   16 minutes ago   189MB
backend      00        e48cc776d20c   2 hours ago      1.09GB
 
 

Just by changing the base image, the container image size went from 1.0GB to 114MB with very minimal work. Next I will explore further optimizations like multi-stage builds, and only add to the container image what is needed to run the application