Integrating Jenkins and SonarQube
This tutorial uses the same Jenkins configuration as the Jenkins with access to hosts Docker engine tutorial. If you did any configuration in jenkins-host-docker directory, sync the project names with -p
/--project-name
option or COMPOSE_PROJECT_NAME
environment variable to use the same volumes. For example:
# Replace jenkins with jenkins-host-docker, if you used default project name in jenkins-host-docker directory.
# With -p/--project-name argument:
docker compose -p jenkins up -d
# With COMPOSE_PROJECT_NAME environment variable:
export COMPOSE_PROJECT_NAME=jenkins
docker compose up -d
In additions to jenkins
service, we now define a sonarqube
service as well in the docker-compose.yml:
version: "3"
services:
jenkins:
build: ../jenkins-host-docker/
ports:
# Web user interface
- 8080:8080
# Java agents
- 50000:50000
volumes:
# Persistent volume for the Jenkins data
- "jenkins.data:/var/jenkins_home"
# Host systems docker socket
- "/var/run/docker.sock:/var/run/docker.sock"
sonarqube:
image: sonarqube:community
ports:
# Web user interface
- 9000:9000
volumes:
- "sonarqube.data:/opt/sonarqube/"
volumes:
jenkins.data:
sonarqube.data:
Gettings started with SonarQube
To get started with SonarQube, access the Web UI and login with admin:admin
credentials. Create a access token in My account > Security and store the token. Use this access token to authenticate to SonarQube from CI instead of the username and password combination.
In order to test the SonarQube installation, run sonar-scanner
in a code repository. This can be done, for example, by using the sonarsource/sonar-scanner-cli Docker image:
# This command should be run in the repository root directory
docker run \
--rm \
--net host \
-e SONAR_HOST_URL="http://localhost:9000" \
-v ${PWD}:/usr/src \
sonarsource/sonar-scanner-cli \
-D"sonar.projectKey=$(basename ${PWD})" \
-D"sonar.login=${your_sonar_access_token}"
If this succeeds, you are ready to move this analysis into Jenkins.
Using SonarQube from Jenkins pipeline
First, install SonarQube Scanner plugin to your Jenkins instance through Manage Jenkins > Manage plugins menu. Configure SonarQube instance to SonarQube servers section of the Manage Jenkins > Configure System menu: Use http://sonarqube:9000
as the server URL and create a secret text credential for the access token you stored earlier.
Use hosts IP instead of sonarqube
hostname
The sonarqube
domain name is by default only available for containers attached to the same network. Thus the the connection from Jenkins container works with the sonarqube
hostname, but opening these links from the browser will fail.
To define an URL that works in both Jenkins and browser, we could use hosts IP address instead of the sonarqube
hostname. The URL would then be in http://${HOST_IP}:9000
format. On linux systems, you can find your local IP with hostname -I
command. On Windows systems, you can find your local by looking for IP address from the output of ipconfig
command. Configure the with hosts IP to the Manage Jenkins > Configure System menu.
When using URL with hosts IP, you can omit the network argument from the docker agent block and the links from the job view should work as is. In the example Jenkinsfile this can be done by setting attachJenkinsNetwork
to false.
After the SonarQube server is configured to Jenkins, sonar-scanner can be executed in a stage that uses the same sonarsource/sonar-scanner-cli Docker image that was used in the previous step as well. This can be done with a stage level Docker agent:
def attachJenkinsNetwork = true
// If true, the pipeline will attach the SonarQube scanner to the same network
// with Jenkins and SonarQube containers.
def scannerArgs = ''
pipeline {
agent any
stages {
stage ('Prepare') {
steps {
script {
if (attachJenkinsNetwork == true) {
// Get the name of the network that Jenkins container is using.
def net = sh returnStdout: true, script: 'docker inspect $(hostname) -f \'{{ range $k, $v := .NetworkSettings.Networks }}{{ $k }}{{ end }}\''
scannerArgs = "--network ${net.trim()}"
}
}
}
}
stage('Checkout') {
steps {
// Replace the git step below with step that pulls the repository you want to analyze.
git branch: 'main', url: 'https://github.com/cicd-tutorials/feedback.git'
}
}
stage('Analyze') {
agent {
docker {
image 'sonarsource/sonar-scanner-cli'
// In order to be able to use http://sonarqube:9000 we need to be in the same network as Jenkins and SonarQube are in.
args scannerArgs
// To quarantee that the workspace contains the sources pulled in previous stage, we need to use the pipeline level workspace.
reuseNode true
}
}
steps {
// The parameter must match the name you gave for the SonarQube server when configuring it.
withSonarQubeEnv('Sonar') {
// Here, job name is used as the project key and current workspace as the sources location.
sh "sonar-scanner -D'sonar.projectKey=${JOB_NAME}' -D'sonar.sources=${WORKSPACE}'"
}
}
}
}
}
After the pipeline with sonar-scanner run has been executed, the job view in Jenkins should include the SonarQube quality gate status of the linked Sonar Project. Note that in this demo setup these links will not work as the Jenkins uses the http://sonarqube:9000
URL for the SonarQube server which is likely not accessible from your browser. To see the projects in SonarQube, replace http://sonarqube:9000
with http://localhost:9000
in the URL.
Note that this setup should only be used for development. For anything production like, configure SonarQube to use database such as postgres, do not use root or admin credentials, and setup the Jenkins and SonarQube to a suitable private network. See also Jenkins and SonarQube documentation for production usage instructions.