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-scanon the selected Komodo Server, and - a Procedure named
vuln-scanthat 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 withname = "APPRISE_URLS",value = "..."andis_secret = true. The value will then live in your sync git repo, so only do this in a private repo.
2. Apply the resources
Option A - git repo mode (recommended)
- Push this project to a git repository Komodo can reach.
- 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.
- 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.
- Refresh the sync and review/apply the pending changes.
- 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>.
-
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.) -
Edit
komodo/vuln-scan-files-on-host.toml(server,IMAGES). -
Apply the file. It still needs to be readable by Core, which does not mount
/etc/komodoby 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. -
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 = truerebuilds the scanner image on the Komodo server. Layers are cached, so only changes toscan.py/Dockerfilerebuild.auto_pull = falseis 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 = falseavoids 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. |
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.
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.