Sonarqube, Docker and .Net Core
Sonarqube, Docker and .Net Core
SonarQube is a great tool for static code analysis for bugs, vulnerabilities, code smells, coverage etc. Recently, I had the chance to use SonarQube for .NET core projects. As with other emerging platforms, it took quite a bit of effort to set it up and get it working. I have created a repository to demonstrate how SonarQube can be used in a multi-stage Dockerfile to collect coverage stats.
Prerequisites1 .NET core codebase with NUnit based unit tests.2. Docker and docker-compose installed.3. DockStation (optional) for monitoring docker containers.4. coverlet.misbuild for code coverage.
Git repoClone or download sonarqube-netcore-docker git repo to begin with. It contains demo .NET core project, demo unit test project based on NUnit and docker manifesto.
Setup SonarQube ContainerUpon cloning git repo, navigate to sonarqube.docker folder and execute the following command
docker-compose up
The command executes following docker-compose file defining two services. It creates two docker containers sonar-postgres and sonarqube corresponding to the two services. It also creates a network sonarqubenet
Alternatively, You could create sonarqube and postgress container using following commands
Navigate to http://localhost:9000 and log into sonarqube using admin/admin as user/pass. Follow the on-screen instruction to complete initial setup. The prompt will ask to create a token and a project key. Use sonar-docker-netcore in both the cases.
Setup the demo app and code coverageNow that SonarQube is up and running, it is time to build the demo app and send coverage stats. So navigate to sonarqube-netcore-docker folder. It contains another docker-compose.yml file defining sample-console-app. Before building the service, we need to tell Dockerfile the sonarqube address. We do that by setting environment variable. Execute following command on the terminal (I ran it on ubuntu terminal) to set sonarqube server address.
export SONARQUBE_ADDRESS=”http://”$((hostname -I | tr ‘ ‘ ‘\n’) | head -n 1)”:9000"
Command above retrieves host ip address and uses it to create sonarqube address. Since sonarqube container port 9000 is mapped to port 9000 of host machine, this will work just fine.
Now navigate to sonarqube-netcore-dockerand execute following command:
docker-compose build
This will build container based on the following Dockerfile
The Dockerfile above is a multi-stage docker file. The first stage compiles and publishes the DLL in /app directory. The second stage copies the DLL and creates entry point for app in the final container. Couple of things here worth mentioning. 1. dotnet sonarscanner command is a wrapper on a java executable. So we need to install JRE.
2. Even though the tests are NUnit tests, the dotnet test command outputs the test artifacts in .trx format. That’s why we need to use sonar.cs.vstest.reportsPaths flag instead of sonar.cs.nunit.reportsPaths.
3. dotnet test can accept .csproj or .sln file as input. In case of .sln, it assumes that all projects in the solution are test projects and it throws error when executing non-unit test project. As a workaround, I have added two .targets files in the solution directory (credit Martin Ullrich).
Once the docker-compose command finishes, navigate to http://localhost:9000.
Troubleshooting 1. /root/sonar-scanner-2.6.1/bin//sonar-scanner: 103: exec: : Permission denied
→Install JRE.2. The following projects do not have a valid ProjectGuid and were not built using a valid solution (.sln) thus will be skipped from analysis
→ Add following snippet into .csproj file. ProjectGuid can be obtained from .sln file if the project is part of a solution. Otherwise a Guid generation tool can be used.
<PropertyGroup> <ProjectGuid> …</ProjectGuid></PropertyGroup>