DevOps Peach

Security (DevSecOps) · SAST with SonarQube · Lesson 2 of 4

SonarQube architecture: scanner, server, database

The scanner runs on the CI machine, analyses source files and sends a report; the server has a web server, an Elasticsearch search server and a compute engine that processes reports and stores them in the database; configure the scanner with sonar-project.properties or -D.

Practice interactively →

Three main blocks

flowchart LR
  subgraph CI["CI / dev machine"]
    SC["SonarScanner"]
  end
  subgraph SRV["SonarQube server"]
    WEB["Web server<br/>UI + Web API"]
    ES["Search server<br/>Elasticsearch"]
    CE["Compute engine"]
  end
  DB[("Database<br/>PostgreSQL")]
  SC -- "analysis report" --> WEB
  WEB --> CE
  CE --> DB
  CE --> ES
  WEB <--> ES
Component Job
Scanner Runs on the build machine, reads source, applies rules and sends an analysis report to the server
Web server The user interface and Web API (including the endpoint that receives reports)
Search server Elasticsearch, indexing issues and components for fast search
Compute engine Processes reports in a background queue, computes metrics, updates the Quality Gate, writes to the DB
Database Stores metrics, issues, history and configuration (Quality Profiles, Gates, users)

The scanner does not store results itself: it sends the report and the compute engine processes it asynchronously. So right after the scanner finishes, the Quality Gate may have no result yet, which is why pipelines need a waiting step.

Production uses PostgreSQL (or SQL Server, Oracle); the embedded database is for trials only. Elasticsearch needs a higher vm.max_map_count on the Linux host, so Docker setups usually require sysctl -w vm.max_map_count=524288.

Scanner types

Scanner Use when
SonarScanner CLI (sonar-scanner) Generic projects, called from a shell
SonarScanner for Maven / Gradle Java projects (mvn sonar:sonar)
SonarScanner for .NET C# projects
CI plugins Jenkins, GitHub Actions, GitLab, Azure DevOps

Configuring the scanner

# sonar-project.properties at the repo root
sonar.projectKey=example-org_myapp
sonar.projectName=myapp
sonar.sources=src
sonar.tests=tests
sonar.exclusions=**/vendor/**,**/*.min.js
sonar.javascript.lcov.reportPaths=coverage/lcov.info

Or pass them on the command line:

sonar-scanner -Dsonar.projectKey=example-org_myapp -Dsonar.sources=src \
  -Dsonar.host.url=http://localhost:9000

Put the authentication token in the SONAR_TOKEN environment variable rather than in a file or the command (older versions used sonar.login).

Traps

Practice interactively →