How to install SonarQube locally or in production to check your code for vulnerabilities, performance and maintainability

Introduction

From Wikipedia: SonarQube (formerly Sonar) is an open-source platform developed by SonarSource for continuous inspection of code quality to perform automatic reviews with static analysis of code to detect bugs and code smells on 29 programming languages. SonarQube offers reports on duplicated code, coding standards, unit tests, code coverage, code complexity, comments, bugs, and security recommendations. SonarQube can record metrics history, evolution graphs and provides fully automated analysis and integration with Maven, Ant, Gradle, MSBuild and continuous integration tools (Atlassian Bamboo, Jenkins, Hudson, etc.). In other words it checks if what your team has written is secure, performs well, it is tested and easy to maintain.


A picture with a teenager starring. the caption sais looking at your code after one year. Did I wrote that?

What does SonarQube checks

SonarQube raises an issue every time a piece of code breaks a coding rule. The set of coding rules are defined by the associated Quality Profile for each language in the project. Quality profiles define the set of rules to be applied during code analysis.

Every project has a quality profile set for each supported language. When a project is analyzed, SonarQube determines which languages are used and uses the active quality profile for each of those languages in that specific project.

Bellow we see the failure of a project passing its quality gate of the Apache Struts 2 framework Struts 2 – The Apache Software Foundation (sonarcloud.io)

Apache Struts 2 Sonarcloud failure results

Issue types

There are three types of issues:

  • Bug: A coding mistake that can lead to an error or unexpected behavior at runtime.
  • Vulnerability: A point in your code that’s open to attack.
  • Code Smell: A maintainability issue that makes your code confusing and difficult to maintain.

Issue severity

Each issue has one of five severities:

  • BLOCKER: Bug with a high probability to impact the behavior of the application in production. For example, a memory leak, or an unclosed JDBC connection are BLOCKERs that must be fixed immediately.
  • CRITICAL: Either a bug with a low probability to impact the behavior of the application in production or an issue that represents a security flaw. An empty catch block or SQL injection would be a CRITICAL issue. The code must be reviewed immediately.
  • MAJOR: A quality flaw that can highly impact the developer’s productivity. An uncovered piece of code, duplicated blocks, or unused parameters are examples of MAJOR issues.
  • MINOR: A quality flaw that can slightly impact the developer’s productivity. For example, lines should not be too long, and “switch” statements should have at least 3 cases, are both be considered MINOR issues.
  • INFO: Neither a bug nor a quality flaw, just a finding.

How to install it

Opensource projects

If you have an opensource project then things are quite straightforward and you have nothing to do. Just head to https://sonarcloud.io/ and create an acount. A very handy wizard will guide you through and you will be able to connect your public github, gitlab etc repos with sonarcloud and perform an analysis. Keep in mind that this analysis is public and visible by anyone afterwards.

Private projects

Local Machine

The easiest method is to deploy it using Docker.

Before you start you need to be sure that your Docker host configuration complies with the Elasticsearch production mode requirements and File Descriptors configuration.

For example, on Linux, you can set the recommended values for the current session by running the following commands as root on the host:

sysctl -w vm.max_map_count=524288
sysctl -w fs.file-max=131072
ulimit -n 131072
ulimit -u 8192

Afterwards just run docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 sonarqube navigate to http://localhost:9000 et voilá you are ready to go. Username and password by default is admin . The drawback on this approach is that you dont persist the results to database. This means that after a restart the previous analysis is gone.

In order to cope with this issue you need to connect sonarqube with a database or use persistent volumes. The recommended volumes are:

  • /opt/sonarqube/data: data files, such as the embedded H2 database and Elasticsearch indexes
  • /opt/sonarqube/logs: contains SonarQube logs about access, web process, CE process, Elasticsearch logs
  • /opt/sonarqube/extensions: for 3rd party plugins

If you want to connect it to an external database then you need a bit more tuning. For example lets deploy a postgres database using Docker persisting her data in a Docker volume.

docker run -d 
    --name postgres \
    -p 5432:5432 \
    -e POSTGRES_USER=root \
    -e POSTGRES_PASSWORD= \
    -v postgres:/var/lib/postgresql/data \
    postgres:14

Now lets deploy sonar and connect it to this database

docker run -d \
--name sonarqube \
-p 9000:9000 \
-e sonar.jdbc.url=jdbc:postgresql://postgres/postgres \
-e sonar.jdbc.username=root \
-e sonar.jdbc.password=<postgres password>

Sonarqube should be up and running at http://localhost:9000 again.

Self-hosted Production Environment

Here you need to be more careful. The generic approach is:

  1. Use a CDN
  2. Choose your host wisely
  3. Install a reverse proxy
  4. Encrypt your data at rest and in transit

CDN

There are many free out there. I personally use Cloudflare that comes with a free version and great features. I activate SSL Strict transport mode and with a small amount I can have a very strong firewall activated in front.

Host selection

I personally use and recommend using the latest LTS Ubuntu linux version as a host OS. Other linux and windows distributions which are also welcome by my criteria is to have a stable distribution with many years of support. Good candidates are also AlmaLinux and Debian. If you decide to use linux turn off ssh authentication using username and password and allow only authentication using a certificate.

Reverse proxy

I have written in the past a very detailed article on how to do that, so please refer to Deploying a Quarkus or any java based microservice behind an Nginx reverse proxy with ssl using docker – JEE.gr

Data Encryption

  • Encrypt data at rest. The easiest way is to create encrypted disk volumes in your OS and place the docker volumes there
  • Encrypt data in transit. If you decide to use cloudflare and you follow my article regarding the reverse proxy, then your data are encrypted until you reach your machine. In order to protect yourself from potential eavesdropping you can also:
    • Create an internal docker network
      For example docker network create internal_private_network and change the commands above like bellow

      docker run -d 
          --name postgres \
          --network internal_private_network \
          -p 5432:5432 \
          -e POSTGRES_USER=root \
          -e POSTGRES_PASSWORD= \
          -v postgres:/var/lib/postgresql/data \
          postgres:14
      
      docker run -d \
      --name sonarqube \
      --network internal_private_network \
      -p 9000:9000 \
      -e sonar.jdbc.url=jdbc:postgresql://postgres/postgres \
      -e sonar.jdbc.username=root \
      -e sonar.jdbc.password=<postgres password>
      
    • Activate SSL in the database connection

Conclusion

It is very easy to create a sonarqube instance and check your code. This will help you a lot in the future to write better code and save time from bugs and maintainability issues.

If you liked it please share it!

Sources

 

Passionate Archer, Runner, Linux lover and JAVA Geek! That's about everything! Alexius Dionysius Diakogiannis is a Senior Java Solutions Architect and Squad Lead at the European Investment Bank. He has over 20 years of experience in Java/JEE development, with a strong focus on enterprise architecture, security and performance optimization. He is proficient in a wide range of technologies, including Spring, Hibernate and JakartaEE. Alexius is a certified Scrum Master and is passionate about agile development. He is also an experienced trainer and speaker, and has given presentations at a number of conferences and meetups. In his current role, Alexius is responsible for leading a team of developers in the development of mission-critical applications. He is also responsible for designing and implementing the architecture for these applications, focusing on performance optimization and security.