SonarQube Setup Guide: Install, Configure, and Run Your First Analysis

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:

  1. SonarQube Server — the web UI, rule engine, and results database
  2. SonarScanner — a CLI tool that analyzes your code and sends results to the server
  3. 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:community

Wait 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 -d

Creating Your First Project

  1. Log in to http://localhost:9000
  2. Click Create Project → Manually
  3. Enter a Project key (e.g., my-project) and Display name
  4. Click Set Up
  5. Choose Locally for analysis method
  6. 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-cli

Option 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.xml

Running Your First Analysis

sonar-scanner \
  -Dsonar.projectKey=my-project \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=your-token-here

The scanner will:

  1. Index your source files
  2. Apply language-specific analyzers
  3. Send results to the SonarQube server
  4. 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 SUCCESS

Reading 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:

  1. Set up a Quality Gate — the pass/fail threshold that blocks deployments (covered in the quality gates post)
  2. Integrate with your CI/CD pipeline — run the scanner on every PR
  3. Configure branch analysis — track quality per branch (requires Developer Edition or SonarCloud)
  4. 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.

Read more

Start now free