How to Setup SonarQube With Flutter Using Docker on Apple Silicon Mac in 8 Steps
Flutter and SonarQube for Static Code Analysis
First, if you are reading this article, you are probably interested in Flutter
app development so that we can skip the introductions there.
What about SonarQube
? That's one of the tools any dev should be aware of: the guardian of high code quality.
And what's Docker
? It's an open-source containerization platform. Think about having a much lighter virtual machine with everything you need already preconfigured, just one tap away from deployment.
There are tones of articles and YouTube
videos on the topic, so I won't cover it in detail in this post.
So let's dive in:
1. Download and install Docker
Head up to https://docs.docker.com/engine/install/ and install the Docker Desktop
version for your OS.
It has support for Apple Silicon, so big kudos on that.
After downloading and running it for the first time, head up to https://hub.docker.com to create an account. We can assume for now a free account is all we need.
In case you get confused about what the Docker Id
is: that's your username.
2. Download the SonarQube image and create your container
Assuming you want to start with the free Community version
you can run from your terminal:
docker pull sonarqube:9.3-community
You may end up with an error like:
no matching manifest for linux/arm64/v8 in the manifest list entries
At the time of the writing, there is no official Apple Silicon support, so if you want the 9+ version of SonarQube
you can try that, but I don't recommend it since it will work very slowly, and if some task takes more than 30 sec of loading on an Apple Silicon, at least in its first year, then it is not worth it.
The below command will force us to download the Docker image for our architecture, but it will work as emulated, which means super slow, hence my comment.
docker pull sonarqube:9.3-community --platform linux/amd64
3. Throw away point 2, and let's try again!
So let's forget about this and find an unofficial Docker image that can work for our Silicon chip (if you are wondering, it is not some random image, it is something a lot of devs are using):
docker pull mwizner/sonarqube:8.9.5-community
The next step is to create our container/app, but first, we will check the image that we have just downloaded.
docker images
REPOSITORY TAG IMAGE ID mwizner/sonarqube 8.9.5-community f5e2e7d2d122
Let's give the name sonarqubeapp
to our container and use the image ID from the above:
docker create --name sonarqubeapp -p 9000:9000 f5e2e7d2d122
Now, let's start our container:
docker start sonarqubeapp
After loading for 15–20 seconds, you can go to http://localhost:9000 and have a running website. For starting, use admin/admin as username and password.
4. Get a plugin for analyzing Dart and Flutter
At the moment of writing, there is no official support for Dart
and Flutter
from SonarQube
, but long live GitHub
and the community.
There is already a plugin/extension that can be downloaded at https://github.com/insideapp-oss/sonar-flutter.
Go to Releases
and take the latest one. In our case, it means sonar-flutter-plugin-0.4.0.jar
5. Copy the .jar plugin to the container
Head up to the Downloads
folder or where the plugin was downloaded and run this command
docker cp sonar-flutter-plugin-0.4.0.jar sonarqubeapp:/opt/sonarqube/extensions/plugins
We are doing a file copy by using docker cp
since the container’s filesystem is not visible to us from an external view. Similar to Sandbox on iOS if you like.
sonarqubeapp
is the container's name, and after :
it's the path to the plugins folder inside the container.
Then we need to restart the container for the plugins to refresh.
docker restart sonarqubeapp
If all the steps so far were successful, then inside the Portal, we should be able to see something similar:

6. Download SonarScanner
The scanner will enable us to upload the local results to the Portal to display the data.
It can run from a Docker image with access to the source repository, but we will focus on a local installation for now.
Head up to https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/ and download the archive and unzip the folder in your home folder.
Be sure to add the path to your .bash_profile
or .zshrc
or whatever shell config you may have on your system so that the command will be visible everywhere and then restart your terminal.
export PATH="$HOME/sonar-scanner-4.7.0.2747-macosx/bin:$PATH"
7. Create the config file
As a final step, we need a configuration file in the root of the Flutter
project that will exchange some information between the source code and the SonarQube
Portal.
Lines 2–4: you will get them after creating a new project inside the Portal.
8. Give it a go!
In the final step, let's put it all together and go to the root of the Flutter
project and run the following:
flutter pub get # just in case
flutter test --machine --coverage > tests.output
sonar-scanner
It will upload our test results and details about the codebase to the Portal for us to analyze. It should look something similar to this if all went smooth:

Bonus point
Remember point 3? We got the initial image from somewhere, then we configured it to suit our particular case.
If we want to save the image of the whole setup for usage on another Mac or even distribute it to the world, we can publish our container/app as either a private or public repository.
# First head to your Docker Hub account and create a new repository (either private or public)docker commit sonarqubeappdocker images # get the newly created empty image iddocker tag [Empty Image Id] [Docker Id]/[Repository Name]:[Version]docker push [Docker Id]/[Image Name]:[Version]
Example:
docker commit sonarqubeapp
docker images
docker tag b0dcc123456 myaccount/project-image:1.0
docker push myaccount/project-image:1.0
Next time, since we have already configured everything, we can skip steps 2–5.
Final thoughts
SonarQube
is an excellent tool that can increase your team's velocity and code quality metrics by taking advantage of statistics like code smells, code coverage, duplicated lines, cyclomatic complexity, etc.
It can also be integrated with a CI/CD environment opening a new world of possibilities like decorating your pull requests or setting up your own team's quality guard rails (like all pushed code should have no code smells or test coverage above 75%, for example) and the list can go on.
And this is only a small part of the features.
Let's go #data-driven
!!!