Local SonarQube + .NET! Catch Bugs Before They Catch You!!!
If you’ve been coding in C# for a while, you’ve probably run into that dreaded moment during a pull request:
“Hey, can you add unit tests?”
“Why are there magic strings?”
“You missed a null check here…”
Wouldn’t it be nice if a robot pointed out those things before your teammates did? Enter SonarQube, a fantastic tool for static analysis and continuous inspection of your codebase.
Today, we’ll cover:
- Running SonarQube locally with Docker Compose
- Setting up a manual project in SonarQube UI
- Using .NET CLI (dotnet sonarscanner) to analyze your project with dotnet build
- Integration tips for Visual Studio and VS Code
- Bonus: Running SonarQube on your HomeLab Raspberry Pi
- PowerShell alias trick + NTFY push notifications
Docker Compose for SonarQube
Create a file named docker-compose.yml
:
version: "3.9"
services:
sonarqube:
image: sonarqube:latest
container_name: sonarqube
ports:
- "9000:9000"
environment:
SONAR_ES_BOOTSTRAP_CHECKS_DISABLE: "true"
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_logs:/opt/sonarqube/logs
- sonarqube_extensions:/opt/sonarqube/extensions
db:
image: postgres:15
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
POSTGRES_DB: sonarqube
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_logs:
sonarqube_extensions:
postgres_data:
Run it with:
docker compose up -d
Open http://localhost:9000, login with admin/admin
(and change the password!).
Setting Up a Manual Project in SonarQube
Inside the SonarQube dashboard:
Go to Projects → Create Project.
Choose Manually.
Enter your project name, e.g., MyDotnetApp
.
Generate a project token — copy it, we’ll use it shortly.
That’s it — SonarQube is ready to accept scans.
Wiring the CLI with .NET Build
Install the scanner:
dotnet tool install --global dotnet-sonarscanner
Navigate to your solution folder and run:
dotnet sonarscanner begin `
/k:"MyDotnetApp" `
/d:sonar.login="YOUR_PROJECT_TOKEN" `
/d:sonar.host.url="http://localhost:9000"
dotnet build
dotnet sonarscanner end /d:sonar.login="YOUR_PROJECT_TOKEN"
Head back to the SonarQube dashboard, and you’ll see metrics: code smells, security hotspots, duplicated code, and more.
Visual Studio & VS Code Integration
Visual Studio: Install the SonarLint extension, connect to SonarQube, and bind your solution.
VS Code: Install the SonarLint extension, run “SonarLint: Connect to SonarQube” from the command palette, and bind your workspace.
Both editors now show SonarQube issues live as you type — the same rules as the server.
Bonus: Running SonarQube in a HomeLab (Raspberry Pi)
If you’re into tinkering (and I know many of you are), you don’t need to keep SonarQube tied to localhost
.
With a HomeLab setup — for example, running Docker on a Raspberry Pi 5 — you can deploy SonarQube to your Pi and let it serve all your devices.
Adjust the sonar.host.url
in your CLI calls from http://localhost:9000
to http://raspberrypi.local:9000
(or the Pi’s IP).
Point VS Code and Visual Studio SonarLint plugins at the same URL.
Now your entire dev environment, laptops, and even teammates at home can connect to a single persistent SonarQube instance.
This is especially handy if you’re already running other services on your Pi (Git, Pi-hole, Grafana dashboards). SonarQube fits right into that ecosystem.
Gotchas & Tips
Performance: The first scan will always be slower — the cache speeds things up afterward.
Resource Needs: On Raspberry Pi, give SonarQube enough swap/memory; otherwise it might refuse to start.
CI/CD: Once stable, integrate with GitHub Actions or Azure DevOps to enforce quality gates.
CLI Aliases in PowerShell: Tired of typing the whole scanner command every time? Create a simple alias in your PowerShell profile so you can just type sonar-scan
.
PowerShell Alias with Raspberry Pi Support + NTFY Notification
# Alias to wrap SonarScanner for .NET with default parameters
function sonar-scan {
param(
[string]$ProjectKey = "MyDotnetApp",
[string]$Version = "1.0.0",
[switch]$UsePi, # toggle if you want to target Raspberry Pi instance
[string]$NotifyUrl = "https://ntfy.sh/my-sonarqube" # replace with your ntfy topic
)
$url = "http://localhost:9000"
if ($UsePi) {
# Change raspberrypi.local to your Pi's hostname or IP
$url = "http://raspberrypi.local:9000"
}
try {
dotnet sonarscanner begin `
/k:$ProjectKey `
/v:$Version `
/d:sonar.host.url=$url `
/d:sonar.login="YOUR_PROJECT_TOKEN"
dotnet build
dotnet sonarscanner end /d:sonar.login="YOUR_PROJECT_TOKEN"
# Send NTFY success notification
Invoke-RestMethod -Uri $NotifyUrl -Method POST -Body "✅ SonarQube scan finished successfully for $ProjectKey v$Version"
}
catch {
# Send NTFY failure notification
Invoke-RestMethod -Uri $NotifyUrl -Method POST -Body "❌ SonarQube scan FAILED for $ProjectKey v$Version"
throw
}
}
You can use NTFY to tell you when it is done, you can follow the setup in this post:
Usage:
# Localhost scan
sonar-scan -ProjectKey "MyDotnetApp" -Version "1.2.3"
# Raspberry Pi HomeLab scan + notification
sonar-scan -ProjectKey "MyDotnetApp" -Version "1.2.3" -UsePi
Every time the scan finishes, your phone buzzes with a push notification — no more babysitting builds. 🚀
Architecture Flow (C4 Diagram)

@startuml
!include <C4/C4_Context>
title SonarQube + .NET Quality Flow
Person(dev, "Developer", "Writes C# code")
System_Ext(ide, "IDE (VS / VS Code)", "Editor with SonarLint plugin")
System_Boundary(local, "HomeLab or Local Machine") {
System(cli, "dotnet sonarscanner", "Analyzes code during build")
SystemDb(sq, "SonarQube", "Code quality dashboard & analysis engine")
}
Rel(dev, cli, "Runs `dotnet sonarscanner`")
Rel(cli, sq, "Sends analysis results")
Rel(sq, ide, "Sync rules & issues via SonarLint")
Rel(dev, ide, "Fix issues highlighted in-editor")
' Optional Raspberry Pi home lab representation
System_Ext(pi, "Raspberry Pi (HomeLab)", "Runs SonarQube via Docker")
Rel(cli, pi, "Alternative target for scans")
@enduml
This shows how a developer uses the CLI scanner, results go to SonarQube (local or Pi), and IDE plugins pull down the same rules/issues.
Conclusion
With Docker Compose on your laptop or a Raspberry Pi in your HomeLab, SonarQube becomes a personal code quality dashboard. Add the IDE integrations, the PowerShell alias, and push notifications, and you’ve got a smooth, developer-friendly workflow that keeps your codebase healthy before it ever hits a pull request.
Happy coding!!!