Files
docker-trivy/komodo
2026-10-23 22:37:05 +02:00
..
2026-10-23 22:37:05 +02:00
2026-10-23 22:05:26 +02:00
2026-10-23 22:05:26 +02:00

Running docker-vuln-scan in Komodo

Two ready-to-apply Resource Sync definitions are provided. Use one of them, not both (they declare the same resource names):

File Use when
vuln-scan.toml Komodo should clone this project from git and build the scanner itself.
vuln-scan-files-on-host.toml You copy this project to the Komodo server and want Komodo to use those files.

Both create:

  • a Stack named vuln-scan on the selected Komodo Server, and
  • a Procedure named vuln-scan that redeploys the stack every night, which rebuilds the scanner image and runs one scan.

Alerts for HIGH/CRITICAL findings are sent by the scanner directly through Apprise. You do not need a Komodo Alerter for that part.

Before you start

  • Komodo 2.x with a Server resource (Periphery) on the Docker host whose images you want to scan.
  • The project available to Komodo (git repo, or copied to the host).
  • A reachable Apprise target (Discord, Slack, email, Telegram, ...).

1. Create the APPRISE_URLS variable

In Komodo: Variables → New Variable

Field Value
Name APPRISE_URLS
Value e.g. discord://webhook_id/webhook_token
Secret on

For several targets, separate them with a space:

mailto://user:app-password@gmail.com tgram://bot_token/chat_id

The stack reads this variable through an [[APPRISE_URLS]] interpolation in its environment, so do this before applying the sync.

If you prefer to keep everything in the TOML file, add a [[variable]] block with name = "APPRISE_URLS", value = "..." and is_secret = true. The value will then live in your sync git repo, so only do this in a private repo.

2. Apply the resources

  1. Push this project to a git repository Komodo can reach.
  2. Edit komodo/vuln-scan.toml:
    • server = "server-prod" → your Komodo Server name.
    • repo = "your-org/docker-vuln-scan" → your repository.
    • IMAGES = ... → the images you want to scan.
  3. In Komodo: Syncs → New Resource Sync → Git Repo, then set:
    • the repository and branch,
    • resource_path = ["komodo/vuln-scan.toml"],
    • a git account if the repo is private.
  4. Refresh the sync and review/apply the pending changes.
  5. Open Procedures → vuln-scan → Run to start the first scan now.

Option B - files on the host

Komodo resolves files-on-host paths under the Periphery root directory (default /etc/komodo, mounted at the same path in the standard Komodo compose setup). The stack path is /etc/komodo/stacks/<stack-name>.

  1. Copy the project to the Docker host:

    sudo mkdir -p /etc/komodo/stacks/vuln-scan
    sudo cp -r docker-vuln-scan/. /etc/komodo/stacks/vuln-scan/
    

    (If you changed PERIPHERY_ROOT_DIRECTORY, use that path instead.)

  2. Edit komodo/vuln-scan-files-on-host.toml (server, IMAGES).

  3. Apply the file. It still needs to be readable by Core, which does not mount /etc/komodo by default. Either keep the TOML in a git-based Resource Sync, or create the Stack and Procedure in the UI using the values from the file.

  4. Run Procedures → vuln-scan → Run.

What a run does

Procedure (cron) -> DeployStack -> docker compose build -> docker compose up -d
                                         |
                                         v
                          scanner container runs and exits
                                         |
                         +---------------+---------------+
                         v                               v
                 Apprise alert (HIGH/CRITICAL)   JSON report on disk
  • run_build = true rebuilds the scanner image on the Komodo server. Layers are cached, so only changes to scan.py/Dockerfile rebuild.
  • auto_pull = false is required: the image is built locally and must not be pulled from a registry.
  • ignore_services = ["vulnscan"] tells Komodo that the exited one-shot container is expected in status checks. Because this stack contains only that one service, Komodo may still show the stack as stopped/down between runs. That is normal for a scheduled one-shot job.
  • send_alerts = false avoids daily status noise. Findings are reported by Apprise instead.

DeployStack returns once docker compose up -d has started the container; it does not wait for the scan to finish. The Apprise notification is the result signal. The container exit code (FAIL_ON) is visible in the stack logs.

Where the results are

On the scan server:

/etc/komodo/stacks/vuln-scan/reports/<image>.json

If your Periphery runs with a different root or the stack uses a run_directory, adjust the path accordingly. The Compose volume is ./reports:/reports relative to the stack directory.

Logs:

  • Komodo UI: Stacks → vuln-scan → Logs
  • Shell: docker compose -p vuln-scan logs vulnscan

Customizing

Edit the stack's environment (in the TOML or in Komodo) and re-apply the sync:

Setting Meaning
IMAGES Space separated images to scan. Leave empty to scan the images used by running containers.
DOCKER_SOCK Host path of the Docker socket (e.g. /run/user/1000/docker.sock for rootless Docker).
INCLUDE_SELF true to also scan the scanner's own image when auto-discovering.
APPRISE_URLS Notification target(s); usually kept in the secret variable.
NOTIFY_MIN_SEVERITY Lowest severity that sends an alert (default HIGH).
FAIL_ON Lowest severity that makes the container exit 1 (default HIGH).
IGNORE_UNFIXED true to ignore findings without a fix.
TRIVY_VEX VEX sources: repo, oci, sbom-ref, or local file paths (space separated).
MAX_FINDINGS_IN_BODY Findings listed per notification.

Schedule fields are on the Procedure:

[procedure.config]
schedule_format = "Cron"
schedule = "0 0 3 * * ?"      # seconds minute hour day month weekday
schedule_timezone = "UTC"

To scan every image on the server instead of just the images in use, write the list on the host and mount it:

docker image ls --format '{{.Repository}}:{{.Tag}}' \
  | grep -v '<none>' > /etc/komodo/stacks/vuln-scan/images.txt

Then add - ./images.txt:/images.txt:ro to the vulnscan service volumes and set IMAGES_FILE = /images.txt in the stack environment.

Private registries: add TRIVY_USERNAME, TRIVY_PASSWORD and optionally TRIVY_INSECURE to the stack environment. The Compose file already passes them through to the container.

VEX: set TRIVY_VEX = repo, oci or a combination in the stack environment. For local files, add - ./vex:/vex:ro to the vulnscan service volumes in docker-compose.yml and use a path such as TRIVY_VEX = /vex/app.json.

Troubleshooting

Symptom Fix
Unresolved [[APPRISE_URLS]] / notification errors Create the APPRISE_URLS variable (step 1) and re-apply.
docker-vuln-scan:latest pull error Keep auto_pull = false; the stack builds the image locally.
Stack shows stopped/down between scans Expected: the scanner is a one-shot container. Status alerts are disabled.
No findings at all Check the image reference is correct; Trivy pulls registry images, and the Docker socket covers local-only images.
"No images configured ... nothing to scan" The scanner cannot reach the Docker socket. With rootless Docker set DOCKER_SOCK=/run/user/<uid>/docker.sock, or set IMAGES explicitly.
Procedure success but no alert Success only means the container started. Check stack logs and the Apprise target.
Need Komodo to fail on findings Not covered by DeployStack; use FAIL_ON in CI or trigger the scanner from a Komodo Action that runs docker run --rm and inspects the exit code.

Security note

The scanner mounts /var/run/docker.sock and runs as root inside the container. That is effectively root on the scan host, so only deploy it to servers and Komodo users you trust.