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)
SEGREP_SAST_VERSION0.1.0Native SAST engine (Go build)

The image includes segrep-sast at /usr/local/bin/segrep-sast with rules at /usr/local/share/segrep-sast/rules. See segrep-sast.md.

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 .segrep/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

segrep-sbom (opt-in) writes the same SBOM artifact and can emit a parity report when shadow mode is enabled:

docker run --rm -v "$(pwd):/repo" -e SEGREP_SBOM_PARITY_SHADOW=true security-scanner:local scan /repo --scanners segrep-sbom
# parity report: .segrep/segrep-sbom-parity.json

# segrep-vuln parity report (opt-in)
docker run --rm -v "$(pwd):/repo" -e SEGREP_VULN_PARITY_SHADOW=true security-scanner:local scan /repo --scanners segrep-vuln
# parity report: .segrep/segrep-vuln-parity.json

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)
segrep-sbomTypeScript local lockfile SBOM scanner (opt-in)
segrep-licenseTypeScript local license compliance scanner (opt-in)
segrep-secretsTypeScript native secret detection scanner (opt-in)
GitleaksBinary (GITLEAKS_VERSION)
Checkovpip (CHECKOV_VERSION)
segrep-sastGo binary (SEGREP_SAST_VERSION) + bundled rules
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 .segrep/ in the mount — use read-write volume
segrep-sbom parity not generatedSet SEGREP_SBOM_PARITY_SHADOW=true; report path is .segrep/segrep-sbom-parity.json
segrep-vuln parity not generatedSet SEGREP_VULN_PARITY_SHADOW=true; report path is .segrep/segrep-vuln-parity.json
Checkov skippedNo IaC files detected under scan root (expected for pure app repos)
Self-hosted CI without Docker daemonInstall local scanner binaries (trivy, syft, gitleaks) before running segrep scan steps