Configure SonarQube Scanner CLI to analyze Java, Python, JavaScript, and C# projects with automated quality gates and CI/CD integration. Streamline code quality analysis across your entire development pipeline with Docker and Jenkins automation.
Prerequisites
- SonarQube server running
- Java 11 or later installed
- Network access to SonarQube server
What this solves
SonarQube Scanner enables automated code quality analysis across multiple programming languages in your development pipeline. This tutorial shows you how to set up the scanner CLI, configure it for Java, Python, JavaScript, and C# projects, and integrate it with CI/CD systems for continuous quality monitoring.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you have the latest repositories.
sudo apt update && sudo apt upgrade -y
Install Java and required dependencies
SonarQube Scanner requires Java 11 or later to run properly.
sudo apt install -y openjdk-17-jdk wget unzip curl
Download and install SonarQube Scanner CLI
Download the latest version of SonarQube Scanner and install it to a system directory.
cd /opt
sudo wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip
sudo unzip sonar-scanner-cli-5.0.1.3006-linux.zip
sudo mv sonar-scanner-5.0.1.3006-linux sonar-scanner
sudo chown -R root:root /opt/sonar-scanner
sudo chmod 755 /opt/sonar-scanner/bin/sonar-scanner
Configure environment variables
Set up system-wide environment variables for the SonarQube Scanner.
SONAR_SCANNER_HOME="/opt/sonar-scanner"
PATH="$PATH:/opt/sonar-scanner/bin"
JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
Load the new environment variables and verify the installation.
source /etc/environment
sonar-scanner --version
Configure global scanner properties
Set up the global configuration file with your SonarQube server connection details.
# SonarQube server configuration
sonar.host.url=https://sonarqube.example.com
sonar.login=your-sonarqube-token
Default source encoding
sonar.sourceEncoding=UTF-8
Scanner performance settings
sonar.scanner.javaOpts=-Xmx2048m
Configure multi-language project analysis
Java project configuration
Create a sonar-project.properties file in your Java project root directory.
# Project identification
sonar.projectKey=my-java-project
sonar.projectName=My Java Application
sonar.projectVersion=1.0
Source and binary directories
sonar.sources=src/main/java
sonar.java.binaries=target/classes
sonar.java.libraries=target/dependency/*.jar
Test configuration
sonar.tests=src/test/java
sonar.java.test.binaries=target/test-classes
Coverage reports
sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
Python project configuration
Configure SonarQube Scanner for Python projects with pytest and coverage integration.
# Project identification
sonar.projectKey=my-python-project
sonar.projectName=My Python Application
sonar.projectVersion=1.0
Source configuration
sonar.sources=src
sonar.python.version=3.9,3.10,3.11,3.12
Test configuration
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml
sonar.python.xunit.reportPath=test-reports/pytest.xml
Exclusions
sonar.exclusions=/_test.py,/test_.py,/__pycache__/
JavaScript/Node.js project configuration
Set up scanner properties for JavaScript projects with Jest testing framework.
# Project identification
sonar.projectKey=my-javascript-project
sonar.projectName=My JavaScript Application
sonar.projectVersion=1.0
Source configuration
sonar.sources=src
sonar.javascript.file.suffixes=.js,.jsx
Test configuration
sonar.tests=tests
sonar.test.inclusions=/.test.js,/.spec.js
sonar.javascript.lcov.reportPaths=coverage/lcov.info
Exclusions
sonar.exclusions=node_modules/,build/,dist/**
C# project configuration
Configure the scanner for .NET C# projects with MSBuild integration.
# Project identification
sonar.projectKey=my-csharp-project
sonar.projectName=My C# Application
sonar.projectVersion=1.0
Source configuration
sonar.sources=src
sonar.cs.opencover.reportsPaths=coverage.xml
sonar.cs.nunit.reportsPaths=TestResults/*.xml
Build configuration
sonar.msbuild.testProjectPattern=.[Tt]est.
Exclusions
sonar.exclusions=/bin/,/obj/,**/*.Designer.cs
Set up quality gates and profiles
Configure custom quality gates
Create project-specific quality gate configurations for stricter code quality enforcement.
# Quality gate configuration
sonar.qualitygate.wait=true
sonar.qualitygate.timeout=300
Coverage thresholds
sonar.coverage.exclusions=/Test.java,/test.py,**/*.test.js
Duplication settings
sonar.cpd.exclusions=/Test.java,/migration/**
Analysis mode
sonar.analysis.mode=publish
Configure language-specific profiles
Set up quality profiles for different programming languages with custom rule sets.
# Multi-language project configuration
sonar.projectKey=multi-lang-project
sonar.projectName=Multi-Language Application
sonar.projectVersion=1.0
Multiple source directories
sonar.sources=src/main/java,src/python,src/javascript,src/csharp
Language-specific settings
sonar.java.source=17
sonar.python.version=3.11
sonar.javascript.node.maxspace=8192
sonar.cs.analyzer.projectOutPaths=/bin/,/obj/
Automate CI/CD integration
Jenkins pipeline integration
Create a Jenkins pipeline script for automated SonarQube scanning.
pipeline {
agent any
environment {
SONAR_SCANNER_HOME = tool 'SonarScanner'
PATH = "${SONAR_SCANNER_HOME}/bin:${PATH}"
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'mvn clean compile test-compile'
}
}
stage('Test') {
steps {
sh 'mvn test'
publishTestResults testResultsPattern: 'target/surefire-reports/*.xml'
}
}
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv('SonarQube') {
sh 'sonar-scanner -Dsonar.projectKey=${JOB_NAME} -Dsonar.sources=. -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_AUTH_TOKEN}'
}
}
}
stage('Quality Gate') {
steps {
timeout(time: 10, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
}
}
Docker integration
Create a Docker-based scanning solution for containerized environments.
FROM sonarsource/sonar-scanner-cli:5.0
Install additional tools
USER root
RUN apk add --no-cache nodejs npm python3 py3-pip openjdk17
Copy project files
COPY . /usr/src
WORKDIR /usr/src
Set environment variables
ENV SONAR_SCANNER_OPTS="-Xmx2048m"
ENV SONAR_HOST_URL="https://sonarqube.example.com"
Run analysis
CMD ["sonar-scanner"]
Docker Compose setup
Create a Docker Compose configuration for local development scanning.
version: '3.8'
services:
sonar-scanner:
build:
context: .
dockerfile: Dockerfile.scanner
volumes:
- .:/usr/src
- sonar-cache:/opt/sonar-scanner/.sonar
environment:
- SONAR_HOST_URL=https://sonarqube.example.com
- SONAR_LOGIN=${SONAR_TOKEN}
networks:
- sonar-network
volumes:
sonar-cache:
networks:
sonar-network:
driver: bridge
GitHub Actions integration
Set up automated scanning with GitHub Actions for continuous integration.
name: SonarQube Analysis
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
sonarqube:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Cache SonarQube packages
uses: actions/cache@v3
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Run tests
run: |
mvn clean test
npm test -- --coverage
python -m pytest --cov --cov-report=xml
- name: SonarQube Scan
uses: sonarqube-quality-gate-action@v1.3.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
Verify your setup
Test your SonarQube Scanner configuration with a sample project analysis.
# Verify scanner installation
sonar-scanner --version
java -version
Test connection to SonarQube server
curl -u ${SONAR_TOKEN}: ${SONAR_HOST_URL}/api/system/status
Run analysis on sample project
cd /path/to/your/project
sonar-scanner -Dsonar.projectKey=test-project -Dsonar.sources=. -X
Check analysis results
curl -u ${SONAR_TOKEN}: "${SONAR_HOST_URL}/api/project_analyses/search?project=test-project"
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Scanner command not found | PATH not set correctly | Add /opt/sonar-scanner/bin to PATH in /etc/environment |
| Java heap space error | Insufficient memory allocation | Increase sonar.scanner.javaOpts to -Xmx4096m |
| Connection refused to SonarQube | Wrong host URL or network issues | Verify sonar.host.url and network connectivity |
| Authentication failed | Invalid or expired token | Generate new token in SonarQube and update sonar.login |
| No coverage reports found | Wrong coverage report paths | Verify coverage file paths in sonar.coverage.* properties |
| Quality gate timeout | Server overloaded or slow analysis | Increase sonar.qualitygate.timeout or reduce project scope |
Next steps
- Install and configure SonarQube server with PostgreSQL
- Implement comprehensive Apache Airflow DAG testing strategies
- Configure SonarQube LDAP authentication for enterprise environments
- Set up SonarQube branch analysis with pull request decoration
- Integrate SonarQube with Kubernetes security scanning workflows
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Default values
SONAR_VERSION="5.0.1.3006"
SONAR_HOST_URL="${1:-https://sonarqube.example.com}"
SONAR_TOKEN="${2:-your-sonarqube-token}"
# Usage function
usage() {
echo -e "${BLUE}Usage: $0 [SONAR_HOST_URL] [SONAR_TOKEN]${NC}"
echo "Example: $0 https://sonar.company.com squ_abc123..."
exit 1
}
# Logging functions
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Cleanup function for rollback
cleanup() {
local exit_code=$?
if [ $exit_code -ne 0 ]; then
log_error "Installation failed. Cleaning up..."
rm -rf /opt/sonar-scanner /tmp/sonar-scanner-*.zip 2>/dev/null || true
sed -i '/SONAR_SCANNER_HOME/d' /etc/environment 2>/dev/null || true
sed -i '/sonar-scanner\/bin/d' /etc/environment 2>/dev/null || true
fi
}
trap cleanup ERR
# Check if running as root or with sudo
if [[ $EUID -eq 0 ]]; then
SUDO=""
elif command -v sudo >/dev/null 2>&1; then
SUDO="sudo"
else
log_error "This script requires root privileges or sudo access"
exit 1
fi
# Detect Linux distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
JAVA_PACKAGE="openjdk-17-jdk"
JAVA_HOME_PATH="/usr/lib/jvm/java-17-openjdk-amd64"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
JAVA_PACKAGE="java-17-openjdk-devel"
JAVA_HOME_PATH="/usr/lib/jvm/java-17-openjdk"
;;
fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
JAVA_PACKAGE="java-17-openjdk-devel"
JAVA_HOME_PATH="/usr/lib/jvm/java-17-openjdk"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
JAVA_PACKAGE="java-17-amazon-corretto-devel"
JAVA_HOME_PATH="/usr/lib/jvm/java-17-amazon-corretto"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
else
log_error "Cannot detect Linux distribution"
exit 1
fi
# Validate arguments if provided
if [ $# -gt 2 ]; then
usage
fi
log_info "Starting SonarQube Scanner installation on $PRETTY_NAME"
# Step 1: Update system packages
echo -e "${BLUE}[1/7] Updating system packages...${NC}"
$SUDO $PKG_UPDATE
log_success "System packages updated"
# Step 2: Install Java and dependencies
echo -e "${BLUE}[2/7] Installing Java 17 and dependencies...${NC}"
$SUDO $PKG_INSTALL $JAVA_PACKAGE wget unzip curl
# Verify Java installation
if ! command -v java >/dev/null 2>&1; then
log_error "Java installation failed"
exit 1
fi
JAVA_VERSION=$(java -version 2>&1 | head -n1 | cut -d'"' -f2 | cut -d'.' -f1)
if [ "$JAVA_VERSION" -lt 11 ]; then
log_error "Java 11 or higher is required. Found version: $JAVA_VERSION"
exit 1
fi
log_success "Java $JAVA_VERSION installed successfully"
# Step 3: Download SonarQube Scanner
echo -e "${BLUE}[3/7] Downloading SonarQube Scanner CLI...${NC}"
cd /tmp
SCANNER_ZIP="sonar-scanner-cli-${SONAR_VERSION}-linux.zip"
SCANNER_URL="https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/${SCANNER_ZIP}"
if ! wget -q --show-progress "$SCANNER_URL"; then
log_error "Failed to download SonarQube Scanner"
exit 1
fi
log_success "SonarQube Scanner downloaded"
# Step 4: Install SonarQube Scanner
echo -e "${BLUE}[4/7] Installing SonarQube Scanner...${NC}"
$SUDO unzip -q "$SCANNER_ZIP" -d /opt/
$SUDO mv "/opt/sonar-scanner-${SONAR_VERSION}-linux" /opt/sonar-scanner
$SUDO chown -R root:root /opt/sonar-scanner
$SUDO chmod 755 /opt/sonar-scanner/bin/sonar-scanner
$SUDO chmod -R 755 /opt/sonar-scanner/bin
$SUDO chmod -R 644 /opt/sonar-scanner/conf/*
rm -f "/tmp/$SCANNER_ZIP"
log_success "SonarQube Scanner installed to /opt/sonar-scanner"
# Step 5: Configure environment variables
echo -e "${BLUE}[5/7] Configuring environment variables...${NC}"
$SUDO tee /etc/profile.d/sonarqube-scanner.sh > /dev/null << EOF
#!/bin/bash
export SONAR_SCANNER_HOME="/opt/sonar-scanner"
export PATH="\$PATH:/opt/sonar-scanner/bin"
export JAVA_HOME="$JAVA_HOME_PATH"
EOF
$SUDO chmod 644 /etc/profile.d/sonarqube-scanner.sh
# Source the environment for current session
export SONAR_SCANNER_HOME="/opt/sonar-scanner"
export PATH="$PATH:/opt/sonar-scanner/bin"
export JAVA_HOME="$JAVA_HOME_PATH"
log_success "Environment variables configured"
# Step 6: Configure global scanner properties
echo -e "${BLUE}[6/7] Configuring global scanner properties...${NC}"
$SUDO tee /opt/sonar-scanner/conf/sonar-scanner.properties > /dev/null << EOF
# SonarQube server configuration
sonar.host.url=$SONAR_HOST_URL
sonar.login=$SONAR_TOKEN
# Default source encoding
sonar.sourceEncoding=UTF-8
# Scanner performance settings
sonar.scanner.javaOpts=-Xmx2048m
EOF
$SUDO chmod 644 /opt/sonar-scanner/conf/sonar-scanner.properties
log_success "Global scanner properties configured"
# Step 7: Create sample project configurations
echo -e "${BLUE}[7/7] Creating sample project configurations...${NC}"
SAMPLES_DIR="/opt/sonar-scanner/samples"
$SUDO mkdir -p "$SAMPLES_DIR"
# Java project sample
$SUDO tee "$SAMPLES_DIR/java-project.properties" > /dev/null << 'EOF'
# Project identification
sonar.projectKey=my-java-project
sonar.projectName=My Java Application
sonar.projectVersion=1.0
# Source and binary directories
sonar.sources=src/main/java
sonar.java.binaries=target/classes
sonar.java.libraries=target/dependency/*.jar
# Test configuration
sonar.tests=src/test/java
sonar.java.test.binaries=target/test-classes
# Coverage reports
sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
EOF
# Python project sample
$SUDO tee "$SAMPLES_DIR/python-project.properties" > /dev/null << 'EOF'
# Project identification
sonar.projectKey=my-python-project
sonar.projectName=My Python Application
sonar.projectVersion=1.0
# Source configuration
sonar.sources=src
sonar.python.version=3.9,3.10,3.11,3.12
# Test configuration
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml
sonar.python.xunit.reportPath=test-reports/pytest.xml
# Exclusions
sonar.exclusions=**/*_test.py,**/test_*.py,**/__pycache__/**
EOF
# JavaScript project sample
$SUDO tee "$SAMPLES_DIR/javascript-project.properties" > /dev/null << 'EOF'
# Project identification
sonar.projectKey=my-javascript-project
sonar.projectName=My JavaScript Application
sonar.projectVersion=1.0
# Source configuration
sonar.sources=src
sonar.javascript.file.suffixes=.js,.jsx
# Test configuration
sonar.tests=tests
sonar.test.inclusions=**/*.test.js,**/*.spec.js
sonar.javascript.lcov.reportPaths=coverage/lcov.info
# Exclusions
sonar.exclusions=node_modules/**,build/**,dist/**
EOF
$SUDO chmod 644 "$SAMPLES_DIR"/*.properties
log_success "Sample project configurations created in $SAMPLES_DIR"
# Final verification
echo -e "${BLUE}Verifying installation...${NC}"
if /opt/sonar-scanner/bin/sonar-scanner --version >/dev/null 2>&1; then
SCANNER_VERSION=$(/opt/sonar-scanner/bin/sonar-scanner --version | head -n1)
log_success "SonarQube Scanner installed successfully: $SCANNER_VERSION"
log_info "Scanner binary: /opt/sonar-scanner/bin/sonar-scanner"
log_info "Global config: /opt/sonar-scanner/conf/sonar-scanner.properties"
log_info "Sample configs: $SAMPLES_DIR"
log_warning "Please restart your shell or run 'source /etc/profile.d/sonarqube-scanner.sh' to use sonar-scanner command"
else
log_error "SonarQube Scanner verification failed"
exit 1
fi
Review the script before running. Execute with: bash install.sh