Sonarqube is an open source platform for continuous inspection of code quality. It is written in Java language and it offers support per languages. It supports various languages like Perl, PHP, Ruby etc. It provides reports on various Code quality analysis (like duplicate coding errors, the percentage of unit testing which got failed and succeeded), Code Coverage and Code complexity.
SonarQube Architecture
The SonarQube Platform is made of 4 components:
A Sonar Runner, source code which you want to analyze, a sonar analyzer which takes the source code and it analysis the code through various processes and finally provides a report which is carried to the database and later it can be used for reporting purposes.
Ideally, we need to choose any of these Java tools namely Ant, Gradle, Maven which invokes the Sonar Runner and will take your source code from the repository. As discussed before, SonarQube provides a Continuous improvement of your source code. It supports many plugins, which will integrate the source code automatically from the repositories.
Next, comes the Sonar Analyser, which analyzes your source code. SonarQube supports more than 20 languages. Based on the language which we need to analyze, we need to enable those plugins which will take care of analyzing those source codes as required.
Squid is a caching server, which is used to hold temporary reports in the cache. Hence, its main advantage is that it maintains the reports in the cache and thereby increases the server performance. Once it completes the analysis of the source code, it sent to the queue where it needs to process these results. After this, it will send it to the database where it's stored. It normally supports h2 database by default. But It's not scalable. Hence, it's always advised to integrate your database server with the SonarQube server. SonarQube supports many database servers like MSSQL, Oracle, PostgreSQL and MySQL. Based on the requirement we can choose the appropriate database which meets our purpose. Hence, It provides flexibility of choosing the required one and integrating it to the SonarQube server. Once you install the Sonar Qube and Sonar Runner, we can access the reports from the URL http://localhost:9000
.
Pre-requisites
- It requires at least 2GB of RAM to run efficiently.
- Minimum of 10 - 20 GB Disk space (this can vary depending how much code you analyze with SonarQube)
- Must be installed on hard drives that have excellent read & write performance.
In this tutorial, I'll explain how to install SonarQube with Nginx on an Ubuntu 16.04 server. Let's start with our installation steps one by one.
1) Update the Base Repositories
First of all, we need to keep our base system up to date by updating and upgrading all software packages on our server.
$apt-get update $apt-get -y upgrade
2) Installing Java Packages
As we already discussed, SonarQube is written in Java language, hence, it requires a Java platform to run. Let's add the required Java repositories and Install Java.
$add-apt-repository ppa:webupd8team/java $apt-get update $apt-get -y install oracle-java8-installer $ java -version java version "1.8.0_111" Java(TM) SE Runtime Environment (build 1.8.0_111-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
You need to accept the license agreement by selecting "yes" in the license window to complete the installation process.
3) Installing MySQL
Our next step is to install our database server. I've planned to integrate MySQL with my SonarQube server. I've followed these steps to install MySQL 5.6.
$add-apt-repository 'deb http://archive.ubuntu.com/ubuntu trusty universe' $apt-get update $apt install mysql-server-5.6 $apt install mysql-client-5.6 Reading package lists... Done Building dependency tree Reading state information... Done mysql-client-5.6 is already the newest version (5.6.16-1~exp1). mysql-client-5.6 set to manually installed. 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. $systemctl start mysql
During the installation step, you can set your MySQL root password. After installing MySQL, make sure to restart the service and secure your MySQL installation by running the secure installation script as below:
$ mysql_secure_installation NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MySQL to secure it, we'll need the current password for the root user. If you've just installed MySQL, and you haven't set the root password yet, the password will be blank, so you should just press enter here. Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password ensures that nobody can log into the MySQL root user without the proper authorisation. You already have a root password set, so you can safely answer 'n'. Change the root password? [Y/n] n ... skipping. By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] y ... Success! By default, MySQL comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y - Dropping test database... ERROR 1008 (HY000) at line 1: Can't drop database 'test'; database doesn't exist ... Failed! Not critical, keep moving... - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y ... Success! All done! If you've completed all of the above steps, your MySQL installation should now be secure. Thanks for using MySQL!
4) Creating SonarQube Database
Next, we need to create a database to store our Code Analysis reports. I've created my database and grant all required privileges for the user "sonarqube" to manage the database "sonarqube" using these commands below:
mysql> CREATE DATABASE sonarqube; Query OK, 1 row affected (0.00 sec) mysql> GRANT ALL PRIVILEGES on sonarqube.* to sonarqube@'localhost' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
5) Installing Nginx
These reports need to be served through a Web server. Our next step is to install a Web server. I'm installing Nginx as a reverse proxy to manage my SonarQube server. Using a reverse proxy enables us to leave Sonarqube to run on default port 9000. We need to add the Nginx repository and update the repository packages to carry out the updates.
$wget -c -O- http://nginx.org/keys/nginx_signing.key | sudo apt-key add - --2016-11-15 06:58:17-- http://nginx.org/keys/nginx_signing.key Resolving nginx.org (nginx.org)... 95.211.80.227, 206.251.255.63, 2001:1af8:4060:a004:21::e3, ... Connecting to nginx.org (nginx.org)|95.211.80.227|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 1561 (1.5K) [application/octet-stream] Saving to: ‘STDOUT’ - 100%[==================================================================>] 1.52K --.-KB/s in 0s 2016-11-15 06:58:17 (246 MB/s) - written to stdout [1561/1561] OK $echo "deb http://nginx.org/packages/ubuntu/ trusty nginx" | sudo tee -a /etc/apt/sources.list.d/nginx.list > /dev/null $apt-get update $apt-get -y install nginx
6) Configure the Virtual Host for SonarQube
In order to create the virtual host, you just move the default file under the /etc/nginx/conf.d/ to sonarqube.conf. You need to just modify the server name with the SonarQube server name and the document root as below:
server { listen 80; server_name nodenixbox.com; #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { root /usr/share/nginx/sonarqube; index index.html index.htm; location / { proxy_pass http://localhost:9000;} }
Create these document root folders if it doesn't exist.
7) How to Install SonarQube
We need to enable binary .deb package from the SonarQube repository and install it. Let's download and install it using the commands below:
$ echo "deb http://downloads.sourceforge.net/project/sonar-pkg/deb binary/" | sudo tee -a /etc/apt/sources.list.d/sonarqube.list > /dev/null $ apt-get update $apt-get -y install sonar
Sonarqube is not started by default after installation. We'll have to configure Sonarqube before starting Sonarqube service.
8) Configuring SonarQube
We need to open the SonarQube configuration file located at /opt/sonar/conf/sonar.properties
. Modify the database credentials with the one we created as below:
Now Sonarqube is ready, we can start Sonarqube using command below:
$ service sonar start $ service sonar status ● sonar.service - LSB: Sonar Loaded: loaded (/etc/init.d/sonar; bad; vendor preset: enabled) Active: active (exited) since Tue 2016-11-15 07:13:33 UTC; 5s ago Docs: man:systemd-sysv-generator(8) Process: 9062 ExecStart=/etc/init.d/sonar start (code=exited, status=0/SUCCESS) Nov 15 07:13:32 sonarqube01 systemd[1]: Starting LSB: Sonar... Nov 15 07:13:32 sonarqube01 su[9068]: Successful su for sonar by root Nov 15 07:13:32 sonarqube01 su[9068]: + ??? root:sonar Nov 15 07:13:33 sonarqube01 su[9068]: pam_unix(su:session): session opened for user sonar by (uid=0) Nov 15 07:13:33 sonarqube01 sonar[9062]: Starting SonarQube... Nov 15 07:13:33 sonarqube01 sonar[9062]: Started SonarQube. Nov 15 07:13:33 sonarqube01 systemd[1]: Started LSB: Sonar.
First initialization process takes some time to complete. It's needed for database migration with creating the database schema, populating data and generate SecureRandom instance for Session IDs.
We can analyze the SonarQube logs while starting the service, to confirm with the proper functioning.
root@sonar01:~# tail -f /opt/sonar/logs/sonar.log 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0.0260s 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0 rows 2016.11.15 07:14:08 INFO web[][DbMigration] -- create_table("active_rules", {}) 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0.0280s 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0 rows 2016.11.15 07:14:08 INFO web[][DbMigration] -- create_table(:active_rule_parameters, {}) 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0.0250s 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0 rows 2016.11.15 07:14:08 INFO web[][DbMigration] == CreateRulesProfiles: migrated (0.0860s) =================================== 2016.11.15 07:14:08 INFO web[][DbMigration] 2016.11.15 07:14:08 INFO web[][DbMigration] == CreateSnapshotSources: migrating ========================================== 2016.11.15 07:14:08 INFO web[][DbMigration] -- create_table(:snapshot_sources, {}) 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0.0220s 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0 rows 2016.11.15 07:14:08 INFO web[][DbMigration] -- index_exists?(:snapshot_sources, :snapshot_id, {:name=>"snap_sources_snapshot_id"}) 2016.11.15 07:14:08 INFO web[][DbMigration] -> 0.0100s 2016.11.15 07:14:08 INFO web[][DbMigration] -- add_index(:snapshot_sources, :snapshot_id, {:name=>"snap_sources_snapshot_id"}) =============================================================================== 2016.11.15 07:14:55 INFO web[][o.a.c.h.Http11NioProtocol] Starting ProtocolHandler ["http-nio-0.0.0.0-9000"] 2016.11.15 07:14:55 INFO web[][o.s.s.a.TomcatAccessLog] Web server is started 2016.11.15 07:14:55 INFO web[][o.s.s.a.EmbeddedTomcat] HTTP connector enabled on port 9000 2016.11.15 07:14:55 INFO app[][o.s.p.m.Monitor] Process[web] is up 2016.11.15 07:14:55 INFO app[][o.s.p.m.JavaProcessLauncher] Launch process[ce]: /usr/lib/jvm/java-8-oracle/jre/bin/java -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -Djava.io.tmpdir=/opt/sonar/temp -javaagent:/usr/lib/jvm/java-8-oracle/jre/lib/management-agent.jar -cp ./lib/common/*:./lib/server/*:./lib/ce/*:/opt/sonar/lib/jdbc/mysql/mysql-connector-java-5.1.39.jar org.sonar.ce.app.CeServer /opt/sonar/temp/sq-process729761780515088296properties 2016.11.15 07:14:56 INFO ce[][o.s.p.ProcessEntryPoint] Starting ce 2016.11.15 07:14:56 INFO ce[][o.s.ce.app.CeServer] Compute Engine starting up... 2016.11.15 07:14:57 INFO ce[][o.e.plugins] [Ikaris] modules [], plugins [], sites [] 2016.11.15 07:14:58 INFO ce[][o.s.s.e.EsClientProvider] Connected to local Elasticsearch: [127.0.0.1:9001] 2016.11.15 07:14:58 INFO ce[][o.sonar.db.Database] Create JDBC data source for jdbc:mysql://localhost:3306/sonarqube?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance 2016.11.15 07:15:02 INFO ce[][o.s.s.p.ServerFileSystemImpl] SonarQube home: /opt/sonar 2016.11.15 07:15:02 INFO ce[][o.s.c.c.CePluginRepository] Load plugins 2016.11.15 07:15:05 INFO ce[][o.s.s.c.q.PurgeCeActivities] Delete the Compute Engine tasks created before Thu May 19 07:15:05 UTC 2016 2016.11.15 07:15:05 INFO ce[][o.s.ce.app.CeServer] Compute Engine is up 2016.11.15 07:15:05 INFO app[][o.s.p.m.Monitor] Process[ce] is up
Finally, we're done with the SonarQube installation. Now we can access our SonarQube Panel with the URL http://domainname:9000. Initially, we can use "admin" as user and password to login to the Panel.
9) Change the Administrative logins
Once you logged into the Panel, you can change your login credentials to a secure one. Please see the screenshots on how to reset the admin password. You can click on the top right drop down Administrator >> Choose My Account >> Select Security tab to get this option.
10) Managing the Plugins
As discussed in the earlier section, it provides numerous plugins to meet our purpose. We need to enable them based on our requirements. We can enable those plugins from the SonarQube Panel itself. Let's see how we can do it.
Login to the Panel >> Choose the Administration Tab
This provides you two options, one to view the current System information and other an Update Center to install, uninstall and delete plugins. You can also download SonarQube updates from the System Updates tab on this page.
After updating the required plugins it will show a pop-up message to restart machine. Then we can Click "Restart" to update these changes done. An important thing to note regarding the restart is that, in a production environment, we need to schedule the maintenance window for the updates and restart or else, it will affect the organizations due to the downtime.
Conclusion
SonarQube helps you to write good intended, duplication free, unit tested source code which can be understood easily. It also helps you to maintain your code according to the standard coding best practices. One of the most powerful features of SonarQube is that it shows you not only your project health today, but also how it has changed over time. It does that by selectively keeping data from previous analyses. Beyond that, there are an extensive amount of features available in SonarQube to improve the quality of your code. You can start using SonarQube which will help you get your code quality up and make your clients happy!