SonarQube Setup Guide: Install, Configure, and Run Your First Analysis
SonarQube is the most widely used platform for static code analysis — it scans your codebase for bugs, vulnerabilities, code smells, and coverage gaps without executing the code. Getting it running takes about 30 minutes: start the server (Docker is easiest), configure a project, run the scanner, and read the results dashboard. This guide walks through every step.
What SonarQube Does
SonarQube performs static analysis — it reads your source code and applies thousands of rules to find problems:
- Bugs: Logic errors that will likely cause incorrect behavior at runtime
- Vulnerabilities: Security weaknesses like SQL injection risks, hardcoded credentials, or insecure configurations
- Code smells: Maintainability issues that make code harder to understand and change
- Coverage: Which lines and branches are exercised by your test suite
- Duplications: Repeated code blocks that should be extracted
Unlike linters (which focus on style), SonarQube performs deep semantic analysis — it understands data flow, control flow, and the relationships between code units.
Architecture Overview
SonarQube has three components:
- SonarQube Server — the web UI, rule engine, and results database
- SonarScanner — a CLI tool that analyzes your code and sends results to the server
- Database — PostgreSQL (or H2 for local dev) that stores analysis history
For most teams, the server runs on a dedicated host (or Docker container) and the scanner runs in CI/CD pipelines.
Installing SonarQube with Docker
The fastest path to a working SonarQube instance:
docker run -d \
--name sonarqube \
-p 9000:9000 \
-e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true \
sonarqube:communityWait about 60 seconds for startup, then open http://localhost:9000. Default credentials: admin / admin (you'll be prompted to change on first login).
For production use with PostgreSQL:
# docker-compose.yml
version: "3"
services:
sonarqube:
image: sonarqube:community
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
ports:
- "9000:9000"
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_logs:/opt/sonarqube/logs
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
POSTGRES_DB: sonar
volumes:
- postgresql_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_logs:
postgresql_data:docker-compose up -dCreating Your First Project
- Log in to
http://localhost:9000 - Click Create Project → Manually
- Enter a Project key (e.g.,
my-project) and Display name - Click Set Up
- Choose Locally for analysis method
- Generate a token — save it, you'll need it for the scanner
Installing SonarScanner
Option 1: Standalone CLI
# macOS
brew install sonar-scanner
# Or download manually
curl -L https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip -o sonar-scanner.zip
unzip sonar-scanner.zip
export PATH="$PATH:$(pwd)/sonar-scanner-5.0.1.3006-linux/bin"Option 2: Docker
docker run \
--network host \
-e SONAR_HOST_URL="http://localhost:9000" \
-e SONAR_SCANNER_OPTS="-Dsonar.projectKey=my-project" \
-e SONAR_TOKEN="your-token-here" \
-v "$(pwd):/usr/src" \
sonarsource/sonar-scanner-cliOption 3: Build tool plugins
For Maven:
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.10.0.2594</version>
</plugin>For Gradle:
plugins {
id "org.sonarqube" version "4.4.1.3373"
}Configuring Your Project
Create sonar-project.properties in your project root:
sonar.projectKey=my-project
sonar.projectName=My Project
sonar.projectVersion=1.0
# Source directories (relative to project root)
sonar.sources=src
# Test directories
sonar.tests=src
sonar.test.inclusions=**/*.test.ts,**/*.spec.ts
# Language-specific settings
sonar.typescript.lcov.reportPaths=coverage/lcov.info
# Exclusions (node_modules, build output, etc.)
sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**For Java with Maven:
sonar.projectKey=my-java-project
sonar.sources=src/main/java
sonar.tests=src/test/java
sonar.java.binaries=target/classes
sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xmlRunning Your First Analysis
sonar-scanner \
-Dsonar.projectKey=my-project \
-Dsonar.sources=. \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.token=your-token-hereThe scanner will:
- Index your source files
- Apply language-specific analyzers
- Send results to the SonarQube server
- Print a link to the analysis dashboard
A typical output:
INFO: Analysis report generated in 847ms, dir size=2 MB
INFO: Analysis report compressed in 354ms, zip size=1 MB
INFO: Analysis report uploaded in 2s
INFO: ANALYSIS SUCCESSFUL, you can find the results at: http://localhost:9000/dashboard?id=my-project
INFO: Task total time: 32.456 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESSReading the Results Dashboard
The SonarQube dashboard shows:
Reliability — Bug count and rating (A through E):
- A: 0 bugs
- B: At least 1 minor bug
- C: At least 1 major bug
- D: At least 1 critical bug
- E: At least 1 blocker bug
Security — Vulnerability count and rating (same A-E scale)
Maintainability — Technical debt in hours/days and code smell count
Coverage — Percentage of lines and branches covered by tests
Duplications — Percentage of duplicated code blocks
Click any metric to drill into the specific issues. Each issue shows:
- The affected file and line number
- The rule that was violated
- Severity (blocker, critical, major, minor, info)
- Estimated remediation time
- A "Why is this an issue?" explanation
Understanding Rules
SonarQube ships with hundreds of built-in rules per language. Each rule has:
- Type: Bug, Vulnerability, Code Smell, Security Hotspot
- Severity: Blocker, Critical, Major, Minor, Info
- Tags: e.g.,
brain-overload,security,performance
You can customize which rules are active via Quality Profiles (Administration → Quality Profiles). Start with the default profile and tune from there — don't disable rules without understanding them.
Common Configuration Issues
"SonarQube does not support the requested Java version"
Update your Java. SonarQube 10+ requires Java 17+.
Coverage not showing up
You need to run your tests and generate a coverage report before running the scanner:
# For a Node.js project with Jest
npx jest --coverage
# Then scan
sonar-scanner \
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info \
...The scanner doesn't run tests — it only reads the coverage reports your test runner produces.
"WARN: No coverage information will be saved"
Check the path in sonar.coverage.jacoco.xmlReportPaths (Java) or sonar.javascript.lcov.reportPaths (JS/TS). Paths are relative to the project root.
Next Steps
Once your first analysis is running:
- Set up a Quality Gate — the pass/fail threshold that blocks deployments (covered in the quality gates post)
- Integrate with your CI/CD pipeline — run the scanner on every PR
- Configure branch analysis — track quality per branch (requires Developer Edition or SonarCloud)
- Add SonarLint to your IDE — get real-time feedback as you type
SonarQube's value compounds over time. The first analysis gives you a baseline; the trend over weeks and months tells you whether your codebase is getting healthier or degrading.