A Trivy scan inspects your Dockerfile’s base image to find unresolved vulnerabilities that your containers will inherit. Trivy can also look at operating system packages and source code dependencies added via popular package managers.
Trivy has three scan types: container, Git repository, and filesystem directory. We’re focusing on container scans in this article. The Trivy docs provide more information on how you can analyze your source code and its environment.
Trivy’s available on most popular Linux distributions. You might need to add the developer’s repository. You can find the right link for your distribution in the Trivy docs.
If you’d prefer to use a specific version, you can download a binary from the project’s GitHub releases page. There’s also an automated install script that will download the appropriate binary for your operating system.
Finally, Trivy’s got its own Docker image which you can use instead of bare-metal installation:
docker run --rm -v trivy-cache:/root/.cache/ -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:latest
This command binds your
trivy-cache directory to the Trivy container’s cache path. This improves performance by allowing Trivy to cache data outside of Docker between scans.
Your host’s Docker socket also gets mounted into the container. This lets Trivy scan other containers running on the host. Now you’re ready to start finding vulnerabilities.
Trivy’s container engine supports local and remote images. It works with Docker, Podman, exported image archives (
docker save) and images in registries such as Docker Hub and GitHub Container Registry.
You can start a basic scan using the
trivy image command. This accepts an image tag.
trivy image my-image:latest
Trivy will download its vulnerability database on the first run. The database will be cached and reused for future scans.
Scan results are emitted straight to your terminal. The summary at the top shows the detected container operating system and a breakdown of found vulnerabilities by severity. The table provides a full list of issues, including the library each one was found in, a description, and a CVE ID when available.
Reducing the Noise
Trivy supports several flags to let you customize its output. It will default to showing all detected vulnerabilities if no flags are present. This could include vulnerabilities that haven’t been patched in the upstream project.
You can exclude unfixed issues by adding the
--ignore-unfixed flag. This reduces the noise by hiding problems that you won’t be able to resolve.
trivy image --ignore-unfixed my-image:latest
Sometimes you might want to intentionally accept a vulnerability. Not all issues impact all projects equally. If you’re not affected, or you’re willing to take the risk, Trivy will let you omit specific CVE IDs from your scans.
.trivyignore file to your working directory. Enter a list of CVE IDs, one on each line. Trivy will find and use the file when you run a scan. CVEs that are present in
.trivyignore won’t show up in the scan output. It’s a good idea to add a comment to each CVE you exclude; this ensures other contributors are informed why the risk has been accepted.
# .trivyignore # This issue is not relevant to our usage CVE-2021-1234
You can filter to show vulnerabilities of a particular type using the
--vuln-type flag. This accepts either
os as a value.
library will reveal issues arising from programming language dependencies. The
os option scopes the scan to operating system packages.
You can also filter by vulnerability severity. This helps you focus on the issues that matter by hiding relatively insignificant vulnerabilities. Pass in a comma-separated list of CVSS severity levels to include:
trivy image --severity MEDIUM,HIGH,CRITICAL my-image:latest
Now any “low” severity problems will be omitted from the report.
Trivy defaults to a visual table designed for human consumption in a terminal. You can get machine-parsable JSON instead by adding
There’s also support for customized output styles using templates. Several templates are included, such as
trivy image --format template @contrib/html.tpl -o scan.html my-image:latest
This scan will produce an HTML report saved to
scan.html. Graphical reports can be quicker to read and easier to share, especially when many issues are found.
Using Trivy In CI
You can easily incorporate Trivy into your CI scripts. Beware that the exit code is always
0 by default, even if vulnerabilities are found. Add the
--exit-code 1 flag to make Trivy exit with a non-zero code if issues are present.
You’ve got multiple options to get Trivy into your builds. Official integration patterns are available for popular CI providers including GitHub, GitLab, Travis, and CircleCI.
When you build images within your pipeline, you can either run Trivy on the final build output or use the tool within the container. Docker’s multi-stage builds let you reference the Trivy image and abort the build if a scan fails. Make sure you use the
filesystem mode instead of
image, as you’re scanning the running container from the inside.
COPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy RUN trivy filesystem --exit-code 1 --no-progress /
It’s usually best to run Trivy near the end of your
Dockerfile, after all your software dependencies are installed. Run
rm /usr/local/bin/trivy afterward to reduce the size of your final image.
Trivy can run in client-server mode. This moves the vulnerability database to the server, so clients don’t need to maintain their own versions.
Trivy binaries come with server mode built-in. Run
trivy server to start a server instance on your machine. The default port is
4594; you can change this by adding
--listen localhost:8080 and specifying the chosen port.
The server will download the vulnerability database when it starts. It’ll check for updates in the background and automatically pull new versions.
You connect a Trivy client to your server using
trivy client --remote http://localhost:8080 image my-image:latest
If you need authentication, add a
--token flag to the server and the client commands. The server will only accept new clients if they present the correct token.
Using Trivy to scan your Docker containers helps you find vulnerabilities before they become an issue in production. You can be more confident in your containers by regularly checking for outdated OS packages and programming language dependencies.
Trivy acquires its vulnerability lists from several different sources. Some of those sources specify non-commercial use only, so you should check that your project’s compliant before you add Trivy to your builds.