In this article I want to describe how I run a SonarQube instance (that I intend to use from my automated CI/CD pipeline) on OCI, using a simple VM and a simple Docker container image. The VM gets a public IP address and I need to SSH into it in order to install Docker and run the SonarQube image. Note: SonarQube automatic is a static code analysis and review tool to detect bugs, vulnerabilities, and code smells in code programmed in one of the 20+ supported languages. There are multiple versions of SonarQube but in this article I will work with the popular community edition which is free and open source.
- Get yourself an OCI Tenancy (could be a free trial);
- Login to the console and open CloudShell
- Create a Compute instance with an always free shape; download the generated SSH keys and write down the public IP assigned to the VM
- Create an NSG (Network Security Group) associated with the VNIC of the VM and Setup Ingress Rule to open up the port required for SonarQube
- SSH into the VM, install Docker
- Run Docker Container Image for SonarQube
- Access the service provided by the container image at the public IP address of the VM: have some code analyzed
- (in a follow up article) integrate SonarQube in CI/CD pipelines
Steps in more detail:
2. Login to the console and open CloudShell
3. Create a Compute instance, save the generated SSH key and write down the public IP assigned to the VM
In the OCI Console Menu, navigate to Compute | Instances:
Select the desired Compartment context and click on Create Instance:
I have accepted mostly default values. I defined the name for the instance : docker-vm and selected a pre-existing compartment. I have selected an existing virtual network and a public subnet within that network. I have also indicated that I want a Public IP address to be assigned. You can also easily request a new VCN and subnet to be created for this VM to join. You can also easily change the shape or image for the VM.
I will configure the networking security after I create the VM.
I want OCI to generate an SSH key pair and I have made sure to download the keys (especially the private key – there is no chance of getting that key at a later moment after the VM has been created.
I do not feel the need for any additional changes to the default values, so I am ready to create the VM:
4. Create an NSG for the VM’s VNIC with proper ingress rules for SonarQube
Up until today I would now have created a network security list for the subnet of which the VM is now a member. However, I have just read about NSG or network security groups and they seem to offer a better, more fine grained approach: with Security lists you define a set of security rules that applies to all the VNICs in an entire subnet. A subnet can be associated with a maximum of five security lists. Any VNICs that are created in that subnet are subject to the security lists associated with the subnet. With a Network security group (NSG) you define a set of security rules that applies to a group of VNICs of your choice. In this case that will be a single VNIC for the docker-vm compute instance.
Create an NSG (Network Security Group) and Setup Ingress Rules to open up the port required for SonarQube
Open the page for the VCN with which the VM is associated. Click on the Network Security Groups section and press the Create Network Security Group button.
Edit the properties of the NSG. First the name:
then the ingress rule:
Source CIDR is set to 0.0.0.0/0; along with Source Port Range left blank (i.e. All) this means that this rule applies to any client. Protocol is TCP, all source ports are allowed and the destination port is limited to port 9000 (it could be any other old port that we can map to port 9000 in the Docker container).
Click on Create.
Next, we want to associate the VMs primary VNIC with this new NSG that should allow traffic to the VM. Bring up the instance details page for the VM.
Click on the edit link for Network Security Groups in the Primary VNIC section.
A list of NSGs in the VCN is shown. Select the desired one.
Press Save Changes. The NSG and its ingress rule are now associated with the VMs primary VNIC. This means that network calls to the public IP address of the VM to port 9000 should be allowed through to the VM – where it should be routed to the Docker container where SonarQube is listening.
5. SSH into the VM and install Docker
At this point, we have a running VM instance. It has a fresh Oracle Linux 7.8 Operating System. But not yet Docker. Let’s open a terminal window into the VM using SSH (or using PuTTY on Windows), using this command:
ssh opc@public-id-address -i rsa-private-key-file
Replace the public-id-address with the public IP assigned to the VM. Replace rsa-private-key-file with a reference to the downloaded file that contains the SSH private key (note: my SSH login failed when the private key file did not have the .pem extension):
To install Docker into the VM, execute these commands:
sudo yum-config-manager –enable ol7_addons
sudo yum install docker-engine -y
sudo systemctl enable docker
sudo systemctl start docker
Then verify if Docker is running, for example with
sudo docker ps
And run a test container with
To run Docker as a non-root user, read these instructions.
6. Run Docker Container Image for SonarQube
With Docker installed, we can now run the container image of our choice. In this case: SonarQube.
On the Docker Hub, you can find the information you need to get started. Because SonarQube uses an embedded Elasticsearch, make sure that your Docker host configuration complies with the Elasticsearch production mode requirements and File Descriptors configuration. By default, the image will use an embedded H2 database that is not suited for production. For a proper environment (not my R&D type of thing) you would need to use volumes mapped into the container to store data outside the ephemeral container.
To make sure my SonarQube will work, I have executed these commands:
sudo sysctl -w vm.max_map_count=262144
sudo sysctl -w fs.file-max=65536
Now this single command suffices to get it going:
sudo docker run -d –restart always –name sonarqube -p 9000:9000 sonarqube
It took close to 90 seconds for the image layers to be downloaded and the container to get started.
A local “curl localhost:9000” returns an HTML document as response, that looks good.
Check inside the container once it’s running:
7. Access the service provided by the container image at the public IP address of the VM: have some code analyzed
Open URL http://public-ip-address:9000 in a browser. It took me a few attempts to get a proper response (at first in Chrome I got a network error reported, then in Edge I could access SonarQube in my VM and subsequently Chrome started working too; perhaps it just takes a long time for SonarQube (in this limited shape VM) to get ready.
Here is what it eventually looked like in my browser:
8. First very simple steps in SonarQube
Login with admin/admin:
and check for example the rationale for the with statement:
To scan a code base:
- create a project in SonarQube
- download scanner to your local environment
- configure the remote SonarQube server (the Docker VM on OCI) with the scanner
- run the scanner locally on the local code base ; the results are submitted to the SonarQube server and can be inspected in the Web UI
Create a SonarQube project, generate a token for the project (to tie scan results to the Sonarqube server)
Enter the name for the token, then generate the token for this project:
The token is generated, save it for later usage with the scanner:
Indicate characteristics for the project technology and the environment in which you want to run the scanner (in my case, my Windows laptop):
Press Download button to download the scanner for the platform. The web page is brought up:
Download the scanner. For Windows, I get a Zip file. I extract the contents to the local directory c:\research:
Edit the file sonar-scanner.properties in the conf directory; set the value for the sonar.host.url property:
Add the bin directory to the Windows PATH environment variable:
To verify the installation and configuration is valid, I can run the statement sonar-scanner.bat –h :
Now I can run scans in any directory tree with for example Node JS applications – and send the results to the Sonarqube server. In the root of such a tree I should create a file called sonar-project.properties that contains a property called sonar.projectKey. The value of this property should correspond to the project in Sonarqube server, in my case my-first-sonarqube-project.
I can start the analysis on the command line simply by typing sonar-scanner:
It took about one and a half minute for the analysis to complete.
The results have been uploaded to the SonarQube server and should now be visible in the browser.
Wow. No issues, just one warning. To be honest: the project contained very little code of my own. And I am not even sure which rules were checked. But still. Better green than orange or red.
Let’s introduce a code smell. Then scan again.
After making some changes to the code – introducing deliberate vi0lations of some of the rules – I scanned again.
This second time the code analysis only takes 31 seconds.
The results are clear – my project went from green to red:
When drilling down on the details, this is what I am told:
I have undone all changes. The result of the rescan shows my return to normal:
In a follow up article, integrate SonarQube in CI/CD pipelines
This article describes the non-containerized installation of SonarQube on Linux. It seems a lot more complicated than simply running a Docker container. So that is what I did.
OCI Documentation on NSG (Network Security Group): https://docs.cloud.oracle.com/en-us/iaas/Content/Network/Concepts/networksecuritygroups.htm?Highlight=nsg
My earlier article on running a(ny) Docker Container image on an always free VM on OCI was a useful guide.
Yashint’s article on running SonarQube in a Docker Container (and going through the first explorations) was also helpful.
My next step will involve Visual Builder Studio’s Build pipelines that can make use of an external SonarQube server for code analysis, as is described here.