DEV Community

Cédric Teyton for Promyze

Posted on • Updated on

Deploy SonarQube 8.9 with Docker on Ubuntu, and set Gitlab CI integration

SonarQube is one the most popular static analysis tool, mainly because it exists since 2008 and is open-source, easing its adoption in the IT industry.

In this post, we'll show how to deploy the latest SonarQube LTS Community Edition so far (8.9), with a PostgreSQL DB and using Docker. We're using Ubuntu 20.04 but, as we use Docker, you may only have to adapt the Docker installation and hardware requirements sections. We'll finally demonstrate how to run a SonarQube analysis using Gitlab CI for a Java project.

🚢 Install Docker and Docker Compose

If not already done, the first step is to install Docker and Docker Compose. The official documentation already has everything you need, but we'll give you the basics steps for a fresh install of Docker on your server :

$> sudo apt-get update
$> sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
$> curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$> echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$> sudo apt-get update
$> sudo apt-get install docker-ce docker-ce-cli containerd.io
$> sudo groupadd docker
$> sudo usermod -aG docker $USER
Enter fullscreen mode Exit fullscreen mode

Logout and Login again to your server, you should be able to run

$> docker run hello-world
Enter fullscreen mode Exit fullscreen mode

And now you can install Docker Compose :

$> sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$> sudo chmod +x /usr/local/bin/docker-compose
Enter fullscreen mode Exit fullscreen mode

🏵️ Adjust OS settings

SonarQube has some hardware requirements : you should increase the values for those 2 OS settings :

  • fs.file-max: "The value in file-max denotes the maximum number of file- handles that the Linux kernel will allocate. When you get lots of error messages about running out of file handles, you might want to increase this limit."
  • vm.max_map_count: "the maximum number of memory map areas a process may have. Memory map areas are used as a side-effect of calling malloc, directly by mmap and mprotect, and also when loading shared libraries."

You should modifiy as root user the /etc/sysctl.conf file to set permanently the values for these 2 parameters :

$> sudo nano /etc/sysctl.conf
Enter fullscreen mode Exit fullscreen mode

Then add this content to the file :

# can be added at the end of the file
fs.file-max=131072
vm.max_map_count=524288
Enter fullscreen mode Exit fullscreen mode

Save, close, and then reload the settings :

$> sudo sysctl --system
Enter fullscreen mode Exit fullscreen mode

🚀 Run SonarQube

Set the following docker-compose.yml file to run both SonarQube and PostgreSQL 12 containers :

version: "3"

services:
  sonarqube:
    image: sonarqube:8.9.2-community
    depends_on:
      - db
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar #tochange
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
    ports:
      - "9000:9000"
  db:
    image: postgres:12
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar #tochange
    volumes:
      - postgresql:/var/lib/postgresql
      - postgresql_data:/var/lib/postgresql/data

volumes:
  sonarqube_data:
  sonarqube_extensions:
  sonarqube_logs:
  postgresql:
  postgresql_data:
Enter fullscreen mode Exit fullscreen mode

⚠️ It would be best if you changed the default password.

You're now ready to run your SonarQube 🚀

$> docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

You can check the evolution of the logs using docker-compose logs -f command. SonarQube is ready when the following logs are displayed :

$> docker-compose logs -f
...
sonarqube_1  | 2021.08.02 07:05:05 INFO  ce[][o.s.ce.app.CeServer] Compute Engine is operational
sonarqube_1  | 2021.08.02 07:05:05 INFO  app[][o.s.a.SchedulerImpl] Process[ce] is up
sonarqube_1  | 2021.08.02 07:05:05 INFO  app[][o.s.a.SchedulerImpl] SonarQube is up
Enter fullscreen mode Exit fullscreen mode

Wait a little bit and you should get the following screen on http://localhost:9000 :

SonarQube Login Page

The next steps will to change the default password for the admin account, and now you'll be ready to start.

🧪 Run analysis on GitLab CI for a Java project

We're now going to run a SonarQube analysis on a project example written in Java 11 and configured with Maven. We also use JUnit and Jacoco to produce code coverage reports. Here is the pom.xml file :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>promyze</groupId>
    <artifactId>java-example-sonarqube</artifactId>
    <version>1.0</version>

    <properties>
        <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
        <sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
        <sonar.language>java</sonar.language>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <release>11</release>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.sonarsource.scanner.maven</groupId>
                <artifactId>sonar-maven-plugin</artifactId>
                <version>3.7.0.1746</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-report-plugin</artifactId>
                <version>2.18.1</version>
            </plugin>

            <!-- Jacoco for code coverage -->
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.3</version>
                <configuration>
                    <append>true</append>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>post-unit-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
Enter fullscreen mode Exit fullscreen mode

Here is the .gitlab-ci.yml file to be put at the root of the repository. We have two steps here : one to compile the project and run the unit tests, and the second to run SonarQube analysis. Note that the image maven:3.6.3-jdk-11 is publicly available. If you're not using Maven, you should browse the SonarQube documentation to check how to run analysis from your context.

stages:
  - test
  - codequality

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"

cache:
  paths:
    - .m2/repository/

test:
  stage: test
  image: maven:3.6.3-jdk-11
  script:
    - mvn install
  artifacts:
    expire_in: 10 min
    paths:
      - target/

sonarqube:
  stage: codequality
  image: maven:3.6.3-jdk-11
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
  script:
    - mvn sonar:sonar
  only:
    - master #you should change this part depending on the context
Enter fullscreen mode Exit fullscreen mode

On GitLab CI, you should set 2 environment variables :

  • SONAR_HOST_URL : This is the full URL of your SonarQube instance.
  • SONAR_TOKEN : An API token, follow this documentation to generate one.

To achieve that GitLab, go to your project/group settings → CI/CD → Variables section. Then you can add the 2 values.

Gitlab_CI_Config

Once you've pushed your .gitlab-ci.yml, your first SonarQube analysis should start, and you should get something like this : 🤗

SonarQubeResult

That was quite simple, don't you think? 🙂

Going further with SonarQube

At Promyze, we commonly help our customers with their projects using SonarQube: setup, migration of versions, configuration, integration with CI/CD, and so on. Such code quality platforms help to define coding rules repositories shared across teams.

Unfortunately, automatic tools can't detect all kinds of issues. That's why developers are doing code reviews and create custom best practices wikis. Promyze is designed for such a purpose; take a tour and check how Promyze can help you to define and share your best coding practices! 🚀

Also, feel free to comment to ask for clarification or suggest improvements to this post. 🙏🏽

Discussion (0)