How to Install and Configure SonarQube on Windows Server 2022
SonarQube is an open-source platform for continuous code quality inspection. It performs static code analysis to detect bugs, code smells, security vulnerabilities, and technical debt across dozens of programming languages. Installing SonarQube on Windows Server 2022 gives development teams a self-hosted code quality gate that integrates with CI/CD pipelines, IDEs, and source control systems. This guide covers the full installation from Java setup through GitHub Actions integration.
System Requirements
SonarQube has specific minimum requirements that must be met before installation:
Java: SonarQube 10.x requires JDK 17. OpenJDK 17 is the standard choice. Both the SonarQube server and sonar-scanner need Java 17 available. SonarQube will not start with older Java versions and the error is sometimes not obvious, so always verify the Java version first.
Database: SonarQube Community Edition supports PostgreSQL (9.6–15), Microsoft SQL Server (2014+), and Oracle. For a new installation on Windows Server 2022, PostgreSQL is the recommended choice due to its performance and free licensing. The embedded H2 database is included but is explicitly unsupported for production — use it only for evaluation.
Memory: Minimum 2 GB RAM dedicated to SonarQube (4 GB recommended for production). SonarQube runs multiple JVM processes and uses Elasticsearch internally.
OS settings: The Elasticsearch component embedded in SonarQube requires specific OS settings that must be configured before startup.
Installing OpenJDK 17
Download and install OpenJDK 17 (Adoptium Temurin distribution is recommended):
# Download Temurin JDK 17 MSI
$jdkUrl = "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_windows_hotspot_17.0.9_9.msi"
Invoke-WebRequest -Uri $jdkUrl -OutFile "C:tempjdk17.msi"
# Install silently
msiexec.exe /i "C:tempjdk17.msi" /qn ADDLOCAL=FeatureMain,FeatureEnvironment,FeatureJarFileRunWith,FeatureJavaHome
# Verify installation
java -version
# Expected: openjdk version "17.0.9" 2023-10-17
Set JAVA_HOME as a system environment variable if the installer did not do so:
[System.Environment]::SetEnvironmentVariable("JAVA_HOME", "C:Program FilesEclipse Adoptiumjdk-17.0.9.9-hotspot", [System.EnvironmentVariableTarget]::Machine)
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::Machine) + ";%JAVA_HOME%bin"
Installing and Configuring PostgreSQL
Download and install PostgreSQL 15 for Windows. After installation, create the SonarQube database and user:
# Run these commands in the PostgreSQL psql shell as the postgres superuser
# Open psql: C:Program FilesPostgreSQL15binpsql.exe -U postgres
CREATE USER sonarqube WITH PASSWORD 'StrongPassword123!';
CREATE DATABASE sonarqube OWNER sonarqube ENCODING 'UTF8' LC_COLLATE='en-US' LC_CTYPE='en-US' TEMPLATE=template0;
GRANT ALL PRIVILEGES ON DATABASE sonarqube TO sonarqube;
q
Verify the connection works from the SonarQube server:
# Test database connectivity
& "C:Program FilesPostgreSQL15binpsql.exe" -h localhost -U sonarqube -d sonarqube -c "SELECT version();"
Downloading and Extracting SonarQube Community Edition
Download the latest SonarQube Community (formerly called Developer in the open-source context) from the official SonarQube downloads page. The Community Edition is free and supports most languages for teams not requiring enterprise features.
# Download SonarQube 10.4 Community Edition
$sonarUrl = "https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-10.4.1.88267.zip"
Invoke-WebRequest -Uri $sonarUrl -OutFile "C:tempsonarqube.zip"
# Extract to installation directory
Expand-Archive -Path "C:tempsonarqube.zip" -DestinationPath "C:SonarQube" -Force
# Rename to a version-independent path
Rename-Item "C:SonarQubesonarqube-10.4.1.88267" "C:SonarQubesonarqube"
The SonarQube directory structure after extraction:
C:SonarQubesonarqube
bin -- platform-specific startup scripts
conf -- configuration files including sonar.properties
data -- embedded database and Elasticsearch data (do not delete)
extensions -- plugins
lib -- JAR files
logs -- log files
temp -- temporary files
web -- web application files
Configuring sonar.properties
The primary configuration file is C:SonarQubesonarqubeconfsonar.properties. Open it in a text editor and configure the database connection and web server settings:
# Database configuration — uncomment and set the PostgreSQL JDBC URL
sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube
sonar.jdbc.username=sonarqube
sonar.jdbc.password=StrongPassword123!
# Web server configuration
# Change the default port from 9000 if needed
sonar.web.host=0.0.0.0
sonar.web.port=9000
# If running behind a reverse proxy (IIS or nginx), set the context path
# sonar.web.context=/sonar
# Elasticsearch configuration
# Set the Java heap size for the search engine (minimum 512m for small instances)
sonar.search.javaAdditionalOpts=-Xms512m -Xmx512m
# JVM heap for the web server
sonar.web.javaOpts=-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError
# JVM heap for the compute engine (analysis processing)
sonar.ce.javaOpts=-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError
# SonarQube data and temp directories (optional overrides)
# sonar.path.data=C:SonarQubedata
# sonar.path.temp=C:SonarQubetemp
For SQL Server instead of PostgreSQL, use the MSSQL JDBC URL format:
sonar.jdbc.url=jdbc:sqlserver://localhost;databaseName=sonarqube;integratedSecurity=false;encrypt=false
sonar.jdbc.username=sonarqube_user
sonar.jdbc.password=StrongPassword123!
Running SonarQube as a Windows Service with NSSM
SonarQube includes a Windows wrapper service script at C:SonarQubesonarqubebinwindows-x86-64StartSonar.bat, but this runs in a console window. For production, install it as a Windows service using NSSM (Non-Sucking Service Manager), which is the most reliable method for running SonarQube as a background service on Windows.
# Download NSSM
$nssmUrl = "https://nssm.cc/release/nssm-2.24.zip"
Invoke-WebRequest -Uri $nssmUrl -OutFile "C:tempnssm.zip"
Expand-Archive -Path "C:tempnssm.zip" -DestinationPath "C:toolsnssm" -Force
# Install SonarQube as a Windows service using NSSM
$nssm = "C:toolsnssmnssm-2.24win64nssm.exe"
& $nssm install SonarQube "C:SonarQubesonarqubebinwindows-x86-64StartSonar.bat"
& $nssm set SonarQube DisplayName "SonarQube"
& $nssm set SonarQube Description "SonarQube Code Quality Platform"
& $nssm set SonarQube Start SERVICE_AUTO_START
& $nssm set SonarQube AppStdout "C:SonarQubesonarqubelogsnssm-stdout.log"
& $nssm set SonarQube AppStderr "C:SonarQubesonarqubelogsnssm-stderr.log"
# Start the service
Start-Service SonarQube
Get-Service SonarQube
Alternatively, SonarQube also includes its own service wrapper. On first run after initial setup, navigate to C:SonarQubesonarqubebinwindows-x86-64 and run:
cd "C:SonarQubesonarqubebinwindows-x86-64"
.InstallNTService.bat
# Then start it
.StartNTService.bat
Initial SonarQube Setup
After starting SonarQube for the first time, monitor the logs to confirm it starts successfully:
# Follow the web server log
Get-Content "C:SonarQubesonarqubelogsweb.log" -Wait -Tail 50
A successful startup ends with lines like: HTTP connector enabled on port 9000 and SonarQube is up. The first startup is slower because the database schema is created.
Open a browser and navigate to http://localhost:9000. Log in with the default credentials: username admin, password admin. You will be immediately prompted to change the admin password — do this before doing anything else.
Open the firewall port if SonarQube should be accessible from other machines:
New-NetFirewallRule -DisplayName "SonarQube" -Direction Inbound -Protocol TCP -LocalPort 9000 -Action Allow
Creating Projects and Tokens
In the SonarQube UI, create a project for each codebase you want to analyze. Go to Projects > Create Project > Manually. Enter a Project Key (unique identifier, no spaces) and a Display Name. Then generate an analysis token by going to Administration > Security > Users > your user account > Tokens, or during project setup. The token is used instead of credentials when running the scanner.
Generate a token via the SonarQube API (useful in automation scripts):
# Create a project token via API
$sonarUrl = "http://localhost:9000"
$adminToken = "your-admin-token"
$response = Invoke-RestMethod -Uri "$sonarUrl/api/user_tokens/generate" `
-Method POST `
-Headers @{ Authorization = "Basic $([Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("admin:$adminToken")))" } `
-Body "name=MyProjectCI&type=PROJECT_ANALYSIS_TOKEN&projectKey=my-project"
Write-Output "New token: $($response.token)"
Running sonar-scanner from Windows
The sonar-scanner CLI tool analyzes code and sends results to the SonarQube server. Download and install it:
# Download sonar-scanner for Windows
$scannerUrl = "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-windows.zip"
Invoke-WebRequest -Uri $scannerUrl -OutFile "C:tempsonar-scanner.zip"
Expand-Archive -Path "C:tempsonar-scanner.zip" -DestinationPath "C:tools" -Force
Rename-Item "C:toolssonar-scanner-5.0.1.3006-windows" "C:toolssonar-scanner"
# Add to PATH
$env:PATH += ";C:toolssonar-scannerbin"
[System.Environment]::SetEnvironmentVariable("PATH", $env:PATH + ";C:toolssonar-scannerbin", [System.EnvironmentVariableTarget]::Machine)
Run an analysis from a project directory:
cd C:ProjectsMyApplication
sonar-scanner `
-Dsonar.projectKey=my-application `
-Dsonar.sources=. `
-Dsonar.host.url=http://localhost:9000 `
-Dsonar.token=sqp_abc123yourtokenhere `
-Dsonar.java.binaries=target/classes `
-Dsonar.exclusions=**/node_modules/**,**/*.test.js
Alternatively, create a sonar-project.properties file in the project root to avoid repeating settings:
sonar.projectKey=my-application
sonar.projectName=My Application
sonar.projectVersion=1.0
sonar.sources=src
sonar.language=js
sonar.host.url=http://localhost:9000
sonar.token=sqp_abc123yourtokenhere
Integrating with MSBuild (SonarScanner for .NET)
For .NET projects, the standard sonar-scanner is not used directly. Instead, use SonarScanner for .NET (formerly SonarScanner.MSBuild), which integrates with the MSBuild build process to properly analyze .NET assemblies, Roslyn diagnostics, and code coverage.
# Install SonarScanner for .NET as a dotnet global tool
dotnet tool install --global dotnet-sonarscanner
# Analysis is a three-step process:
# Step 1: Begin — configure the analysis
dotnet sonarscanner begin `
/k:"my-dotnet-project" `
/d:sonar.host.url="http://localhost:9000" `
/d:sonar.token="sqp_abc123yourtokenhere" `
/d:sonar.cs.opencover.reportsPaths="**/coverage.opencover.xml"
# Step 2: Build — run your normal build
dotnet build --configuration Release
# Step 3: End — collect results and send to SonarQube
dotnet sonarscanner end /d:sonar.token="sqp_abc123yourtokenhere"
To include code coverage, run tests with coverage collection before the end step:
dotnet sonarscanner begin /k:"my-dotnet-project" /d:sonar.host.url="http://localhost:9000" /d:sonar.token="sqp_abc123" /d:sonar.cs.opencover.reportsPaths="coveragecoverage.opencover.xml"
dotnet build
dotnet test --collect:"XPlat Code Coverage" --results-directory coverage -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
dotnet sonarscanner end /d:sonar.token="sqp_abc123"
Quality Gates
A Quality Gate is a set of conditions that determine whether code meets your quality standards. SonarQube ships with a default “Sonar way” quality gate. Navigate to Quality Gates in the SonarQube UI to view or create custom gates.
Common quality gate conditions include:
– New code coverage is less than 80% → fail
– New code has security hotspots without review → fail
– New code has new blocker issues → fail
– Technical debt ratio on new code is above 5% → warn
In CI/CD pipelines, check the quality gate status after analysis using the API:
# Poll for analysis completion and quality gate status
$taskUrl = "http://localhost:9000/api/ce/task?id=$taskId"
do {
Start-Sleep 5
$task = Invoke-RestMethod -Uri $taskUrl -Headers @{ Authorization = "Basic $encodedAuth" }
} while ($task.task.status -eq "PENDING" -or $task.task.status -eq "IN_PROGRESS")
# Get quality gate status
$qgUrl = "http://localhost:9000/api/qualitygates/project_status?analysisId=$($task.task.analysisId)"
$qg = Invoke-RestMethod -Uri $qgUrl -Headers @{ Authorization = "Basic $encodedAuth" }
if ($qg.projectStatus.status -eq "ERROR") {
Write-Error "Quality gate FAILED"
exit 1
}
Write-Output "Quality gate PASSED"
SonarQube with GitHub Actions
Integrate SonarQube analysis into GitHub Actions workflows using the official SonarQube Action:
name: SonarQube Analysis
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
sonarqube:
name: SonarQube Scan
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for SonarQube to analyze git history
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: 17
distribution: temurin
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v2
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
with:
args: >
-Dsonar.projectKey=my-project
-Dsonar.sources=src
-Dsonar.java.binaries=target/classes
- name: SonarQube Quality Gate Check
uses: SonarSource/sonarqube-quality-gate-action@v1
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Store SONAR_TOKEN (your analysis token) and SONAR_HOST_URL (http://your-server:9000) as GitHub Actions secrets. For SonarQube to be reachable from GitHub’s runners, it must be publicly accessible or use a GitHub-hosted runner tunnel solution.
SonarLint IDE Integration
SonarLint is the IDE plugin companion to SonarQube. It runs the same analysis rules locally in real time as developers write code. Install SonarLint from the marketplace in Visual Studio, VS Code, IntelliJ IDEA, or Eclipse.
To connect SonarLint to your SonarQube server (enabling Connected Mode, which syncs quality profiles and quality gates from the server):
In VS Code with the SonarLint extension: open the Command Palette, run “SonarLint: Connect to SonarQube Server”, enter the server URL and a User Token (generate from SonarQube > My Account > Security > Generate Token), and select the project to bind to. Connected Mode ensures developers see the exact same issues locally that the server would report, closing the feedback loop before code is ever committed.
SonarQube on Windows Server 2022 provides a comprehensive code quality platform that integrates throughout the development lifecycle — from IDE feedback during coding, to pipeline quality gates on every PR, to project-level dashboards tracking technical debt over time.