Docker image reference

Build args, bundled tools, worker mode, GHCR publish

The Docker image bundles the CLI (scan) and optional worker (platform queue processing).

For scanning repos locally or in CI, start with the product guide: scan-product.md.

Commands

CommandPurpose
scan /repo [flags]Scan a mounted directory (no platform required)
workerPoll Postgres for queued scans (platform)
worker --drainProcess all queued jobs, then exit

Build

From the repository root:

pnpm docker:build

Or:

docker build -f infrastructure/docker/Dockerfile -t security-scanner:local .

Build args (defaults in Dockerfile):

ArgDefaultTool
TRIVY_VERSION0.71.2Dependency & CVE scanner
SEMGREP_VERSION1.95.0SAST (pip)
SYFT_VERSION1.18.1SBOM generator
GITLEAKS_VERSION8.21.2Secret scanner
CHECKOV_VERSION3.2.428IaC scanner (pip)

Example with pinned versions:

docker build -f infrastructure/docker/Dockerfile \
  --build-arg TRIVY_VERSION=0.71.2 \
  --build-arg GITLEAKS_VERSION=8.21.2 \
  -t security-scanner:local .

Scan (see scan-product.md for full guide)

docker run --rm -v "$(pwd):/repo:ro" security-scanner:local scan /repo
docker run --rm -v "$(pwd):/repo:ro" security-scanner:local \
  scan /repo --scanners all --format json --fail-on high

Syft writes .scantis/sbom.cyclonedx.json inside the scan target — use a read-write mount if you need the file on the host:

docker run --rm -v "$(pwd):/repo" security-scanner:local scan /repo --scanners syft

Worker (platform only)

Process scans queued by the hosted dashboard/API:

docker run --rm --env-file .env security-scanner:local worker --drain

Required in .env:

DATABASE_URL=postgresql://...@neon.tech/neondb?sslmode=require
DASHBOARD_URL=https://your-app.vercel.app

For GitHub PR scans, also set GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY.

See vercel-neon-local-worker.md.

Publish to GHCR

Tag a release:

git tag v0.1.0
git push origin v0.1.0

Workflow: .github/workflows/docker-publish.ymlghcr.io/szaranger/security-scanner:latest

Image contents

ToolInstalled as
TrivyBinary (TRIVY_VERSION)
Semgreppip (SEMGREP_VERSION)
SyftBinary (SYFT_VERSION)
GitleaksBinary (GITLEAKS_VERSION)
Checkovpip (CHECKOV_VERSION)
gitPR clone in worker mode

Scanners use binaries inside the container (not Docker-in-Docker).

Troubleshooting

IssueFix
Permission denied on volumePath must exist; Docker must be able to read the mount
Worker finds no jobsSame DATABASE_URL as Vercel; queue a scan via API or webhook first
PR scan failsSet GitHub App credentials in --env-file
Slow first scanTrivy/Semgrep download rule DBs on first run
No SBOM file on hostSyft writes under .scantis/ in the mount — use read-write volume
Checkov skippedNo IaC files detected under scan root (expected for pure app repos)