Integrate Docker Scout with GitLab CI/CD

Table of contents

The following examples runs in GitLab CI in a repository containing a Docker image's definition and contents. Triggered by a commit, the pipeline builds the image. If the commit was to the default branch, it uses Docker Scout to get a CVE report. If the commit was to a different branch, it uses Docker Scout to compare the new version to the current published version.

Steps

First, set up the rest of the workflow. There's a lot that's not specific to Docker Scout but needed to create the images to compare.

Add the following to a.gitlab-ci.ymlfile at the root of your repository.

docker-build:
image:docker:latest
stage:build
services:
-docker:dind
before_script:
-docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY

# Install curl and the Docker Scout CLI
-|
apk add --update curl
curl -sSfL https://raw.githubusercontent /docker/scout-cli/main/install.sh | sh -s --
apk del curl
rm -rf /var/cache/apk/*
# Login to Docker Hub required for Docker Scout CLI
-docker login -u "$DOCKER_HUB_USER" -p "$DOCKER_HUB_PAT"

This sets up the workflow to build Docker images with Docker-in-Docker mode, running Docker inside a container.

It then downloadscurland the Docker Scout CLI plugin, logs into the Docker registry using environment variables defined in your repository's settings.

Add the following to the YAML file:

script:
-|
if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
tag= ""
echo "Running on default branch '$CI_DEFAULT_BRANCH': tag = 'latest'"
else
tag= ":$CI_COMMIT_REF_SLUG"
echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag"
fi
-docker build --pull -t "$CI_REGISTRY_IMAGE${tag}".
-|
if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
# Get a CVE report for the built image and fail the pipeline when critical or high CVEs are detected
docker scout cves "$CI_REGISTRY_IMAGE${tag}" --exit-code --only-severity critical,high
else
# Compare image from branch with latest image from the default branch and fail if new critical or high CVEs are detected
docker scout compare "$CI_REGISTRY_IMAGE${tag}" --to "$CI_REGISTRY_IMAGE:latest" --exit-code --only-severity critical,high --ignore-unchanged
fi

-docker push "$CI_REGISTRY_IMAGE${tag}"

This creates the flow mentioned previously. If the commit was to the default branch, Docker Scout generates a CVE report. If the commit was to a different branch, Docker Scout compares the new version to the current published version. It only shows critical or high-severity vulnerabilities and ignores vulnerabilities that haven't changed since the last analysis.

Add the following to the YAML file:

rules:
-if:$CI_COMMIT_BRANCH
exists:
-Dockerfile

These final lines ensure that the pipeline only runs if the commit contains a Dockerfile and if the commit was to the CI branch.

Video walkthrough

The following is a video walkthrough of the process of setting up the workflow with GitLab.