Deployment guide

Jenkins SonarQube

Overview

Jenkins is the CI/CD orchestrator, and SonarQube Community Edition is the static-analysis quality gate. This SecureAnyCloud image delivers both with the integration already wired, so a pipeline's withSonarQubeEnv('SonarQube') step works on first boot.

waitForQualityGate also resolves, because SonarQube posts its result back to Jenkins over a pre-configured webhook. Only the free Community Edition of SonarQube (LGPL-3.0) is included. The Developer, Enterprise and Data Center editions are separate commercial products. Jenkins is MIT-licensed.

What you get:

  • Jenkins LTS 2.568.2 (MIT) from the official pkg.jenkins.io/debian-stable APT repository, on OpenJDK 21, bound to 127.0.0.1:8080 with the setup wizard disabled
  • SonarQube Community 10.7 (LGPL-3.0) on OpenJDK 17, bound to 127.0.0.1:9000 under the /sonar context, backed by a local PostgreSQL and its embedded Elasticsearch (vm.max_map_count=524288 persisted)
  • The integration, pre-wired: the Jenkins SonarQube Scanner plugin, a SonarQube server installation that points at the local server with a per-VM analysis-token credential, a SonarScanner tool at /opt/sonar-scanner, a SonarQube-to-Jenkins quality-gate webhook, and a seeded sonarqube-analysis-demo pipeline that runs the whole loop
  • nginx on :80 as the only public listener: / serves Jenkins and /sonar serves SonarQube. nginx uses $http_host so absolute URLs and the webhook stay correct
  • Per-VM secrets, none baked in: the Jenkins admin password, SonarQube admin password (the default admin/admin is rotated and rejected), PostgreSQL role password and SonarQube analysis token are all generated on first boot and written to /var/lib/sac/secrets/sac-credentials.txt (mode 0600 root:root)
  • A dedicated 40 GiB data disk at /var/lib/sonarqube, holding the SonarQube data and extensions and the PostgreSQL data directory
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key, and a VNet with a subnet. Configure the network security group (NSG) to allow inbound TCP 22 (SSH) and TCP 80 (web interface) from your trusted CIDR.

Sizing: the image runs two JVMs (Jenkins, and the SonarQube web and compute engine), an embedded Elasticsearch JVM and PostgreSQL. Measured idle memory for the whole stack is about 4.6 GiB, rising to about 7 GiB while an analysis runs.

Standard_B4ms (16 GiB) is the recommended size for a demo or small team. Smaller sizes cannot host two JVMs plus Elasticsearch and PostgreSQL. For heavier workloads, scale up to a D-series size and add distributed Jenkins agents.

1

Deploy from the Azure Marketplace

Search the Azure Marketplace for "SecureAnyCloud Jenkins SonarQube" and select Create. Choose the Standard_B4ms size and your VNet and subnet. Make sure the NSG allows inbound TCP 22 and TCP 80 from your trusted CIDR.

2

Connect over SSH

Connect to the VM as azureuser:

ssh azureuser@<public-ip>
3

Confirm the stack is running

Run the command below to check the four services. All of them are enabled and started on first boot.

for s in postgresql sonarqube jenkins nginx; do printf '%-14s %s (%s)\n' "$s" "$(systemctl is-active $s)" "$(systemctl is-enabled $s)"; done
4

Read your per-VM credentials

First boot rotates every secret and writes the new values to a file that is unique to this VM. Read it with sudo:

sudo cat /var/lib/sac/secrets/sac-credentials.txt

The file (mode 0600 root:root) contains JENKINS_URL and JENKINS_ADMIN_PASSWORD, SONARQUBE_URL and SONARQUBE_ADMIN_PASSWORD, and SONARQUBE_ANALYSIS_TOKEN. Every value is unique to your VM.

5

Open Jenkins

Browse to http://<public-ip>/ and sign in with admin and the JENKINS_ADMIN_PASSWORD from Step 4. The dashboard lists the pre-seeded sonarqube-analysis-demo pipeline.

6

Open SonarQube

Browse to http://<public-ip>/sonar and sign in with admin and the SONARQUBE_ADMIN_PASSWORD from Step 4. The same nginx front door serves SonarQube under the /sonar path.

To confirm the server is up without signing in, run:

curl -s http://localhost/sonar/api/server/version; echo
curl -s -o /dev/null -w 'sonar /health: %{http_code}\n' http://localhost/health
7

See the integration in action

The seeded sonarqube-analysis-demo pipeline demonstrates the whole loop. Open it in Jenkins. The Stage View shows the SonarQube analysis and Quality gate stages.

Then open SonarQube. The analysed project appears there with its quality gate result.

You can verify the same thing from the shell. The bundled check runs a real sonar-scanner analysis with the per-VM token. It confirms that SonarQube processed the analysis and evaluated the gate:

sudo /usr/local/sbin/jenkins-sonarqube-integration-check.sh
8

How Jenkins and SonarQube are wired together

The SonarQube-to-Jenkins webhook that waitForQualityGate relies on is pre-configured. In SonarQube, open Administration > Configuration > Webhooks to see the Jenkins webhook and its deliveries.

On the Jenkins side, a SonarQube server installation and a SonarScanner tool are already configured under Manage Jenkins > System and Tools. Your own pipelines can use the integration with no setup:

pipeline { agent any stages { stage('SonarQube analysis') { steps { script { def scannerHome = tool 'SonarScanner' withSonarQubeEnv('SonarQube') { sh "${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=my-app" } } } } stage('Quality gate') { steps { timeout(time: 5, unit: 'MINUTES') { waitForQualityGate abortPipeline: true } } } } }

Point a job at your own Git repository and add a sonar-project.properties file, or pass -Dsonar.sources=.... The analysis, token and quality-gate feedback then work with no further configuration.

9

Check the versions

Print the Jenkins, SonarQube and Java versions:

echo "Jenkins: $(curl -sI http://localhost/login | awk '/[Xx]-[Jj]enkins:/{print $2}' | tr -d '\r')"
echo "SonarQube: $(curl -s http://localhost/sonar/api/server/version) (Community Edition)" java -version 2>&1 | head -1

Security notes

  • No default credentials survive first boot. SonarQube's admin/admin is rotated to a per-VM password, and the default no longer works. The Jenkins admin password, PostgreSQL role password and SonarQube analysis token are also generated per VM.
  • Rotate the admin passwords after first login if you wish, and restrict the NSG to your own management CIDR.
  • Add TLS for production. nginx serves plain HTTP on port 80. For internet-facing use, add a TLS certificate (for example with certbot) and restrict access. Both applications build absolute URLs from their configured base URL, so update sonar.core.serverBaseURL and the Jenkins URL if you place the appliance behind a different hostname or your-domain.
  • The web interfaces bind to loopback only. Jenkins (:8080) and SonarQube (:9000) are never exposed directly. nginx on :80 is the single public listener.

Support

SecureAnyCloud images include 24/7 support. Contact sales@secureanycloud.com with the VM name and region for help.

Deploy on Azure

Launch Jenkins CI with SonarQube Quality Gate on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure