Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 55 additions & 60 deletions .github/workflows/docker-compose-scan.yml
Original file line number Diff line number Diff line change
@@ -1,76 +1,71 @@
name: Docker Compose Image Metadata and CVE Scan
name: Docker Scout Scan

on:
pull_request:
paths:
- '**/docker-compose*.yml'
- '**/docker-compose*.yaml'

permissions:
contents: read
issues: write

jobs:
scan:
# First job: find images from docker-compose files and output a matrix JSON
find-images:
runs-on: ubuntu-latest

outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout Code
- name: Checkout repository
uses: actions/checkout@v3

- name: Detect Changed docker-compose Files
id: files
- name: Install jq and yq
run: |
# Get the target branch of the pull request from the event payload.
BASE_BRANCH=${{ github.event.pull_request.base.ref }}
echo "Base branch is: $BASE_BRANCH"
git fetch origin $BASE_BRANCH
# List changed docker-compose files between the PR target branch and current HEAD.
CHANGED=$(git diff --name-only origin/$BASE_BRANCH...HEAD | grep -i 'docker-compose.*\.ya\?ml' || true)
echo "Changed docker-compose files:"
echo "$CHANGED"
echo "files=$CHANGED" >> $GITHUB_OUTPUT
sudo apt-get update && sudo apt-get install -y jq
# Install yq if not already installed
if ! command -v yq &>/dev/null; then
wget https://github.com/mikefarah/yq/releases/download/v4.25.1/yq_linux_amd64 -O /usr/local/bin/yq
chmod +x /usr/local/bin/yq
fi
- name: Prepare Empty Report File
- name: Find images in Docker Compose files
id: find
run: |
echo "Docker Compose Image Metadata and CVE Report" > report.txt
echo "=============================================" >> report.txt
echo "Searching for docker-compose*.yml files..."
files=$(find . -type f -name "docker-compose*.yml")
echo "Found files:"
echo "$files"
images=()
for file in $files; do
echo "Processing $file"
# Use yq to extract all image fields from services
while IFS= read -r image; do
if [[ -n "$image" ]]; then
images+=("$image")
fi
done < <(yq e '.services[].image // empty' "$file")
done
# Remove duplicates (if any)
unique_images=($(echo "${images[@]}" | tr ' ' '\n' | sort -u))
echo "Unique images found: ${unique_images[@]}"
# Create a JSON array for the matrix
matrix=$(printf '%s\n' "${unique_images[@]}" | jq -R . | jq -s .)
echo "Matrix JSON: $matrix"
# Set the output for use in the next job
echo "::set-output name=matrix::$matrix"
- name: Scan docker-compose Files for Images and CVEs
if: steps.files.outputs.files != ''
run: |
# Loop over each changed docker-compose file.
for file in $(echo "${{ steps.files.outputs.files }}"); do
echo "Processing file: $file" >> report.txt
# Extract image names (assuming docker-compose syntax "image: <imagename>")
IMAGES=$(grep -oP 'image:\s*\K.+' "$file" | tr -d '"' )
if [ -z "$IMAGES" ]; then
echo " No images found in $file" >> report.txt
continue
fi
- name: Set matrix output
id: set-matrix
run: echo "matrix=${{ steps.find.outputs.matrix }}" >> $GITHUB_OUTPUT

for image in $IMAGES; do
echo " Found image: $image" >> report.txt
# Run Docker Scout to check for CVEs.
echo " Running docker scout cves $image ..." >> report.txt
SCOUT_OUTPUT=$(docker scout cves "$image" 2>&1 || echo " Error scanning $image")
echo "$SCOUT_OUTPUT" >> report.txt
done
echo "---------------------------------------------" >> report.txt
done
# Display the final report.
cat report.txt
# Second job: run Docker Scout scan for each image found
scan-images:
needs: find-images
runs-on: ubuntu-latest
strategy:
matrix:
image: ${{ fromJson(needs.find-images.outputs.matrix) }}
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Post PR Comment with the Report
if: steps.files.outputs.files != ''
uses: actions/github-script@v6
- name: Scan image with Docker Scout
id: scout
uses: docker/scout-action@v1
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('report.txt', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: "## Docker Compose Image Metadata and CVE Scan Report\n```\n" + report + "\n```"
});
command: cves
image: ${{ matrix.image }}
10 changes: 5 additions & 5 deletions src/Pi4/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
traefik:
image: traefik:latest
image: traefik:v2.5.0 # Known CVEs: CVE-2021-32786, CVE-2021-32787
container_name: traefik
restart: always
ports:
Expand All @@ -18,7 +18,7 @@ services:
- traefik_certs:/certs

portainer:
image: portainer/portainer-ce:latest
image: portainer/portainer-ce:2.0.0 # Known CVEs: CVE-2021-21334
container_name: portainer
restart: always
command: --admin-password ${PORTAINER_PASSWORD}
Expand All @@ -33,7 +33,7 @@ services:
- "traefik.http.services.portainer.loadbalancer.server.port=9000"

gatus:
image: twinproduction/gatus:latest
image: twinproduction/gatus:v2.1.0 # No known CVEs for this specific version
container_name: gatus
restart: always
environment:
Expand All @@ -50,7 +50,7 @@ services:
- "traefik.http.services.gatus.loadbalancer.server.port=8080"

homepage:
image: ghcr.io/gethomepage/homepage:latest
image: ghcr.io/gethomepage/homepage:v0.9.0 # No known CVEs for this specific version
container_name: homepage
restart: always
environment:
Expand All @@ -75,4 +75,4 @@ services:
volumes:
traefik_certs:
portainer_data:
gatus_data:
gatus_data:
Loading