本文需要啓動的服務如下:

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker

 因為sonar最新版本不支持掃描多分支,所以本次演示使用了最新版本和支持多分枝掃描的老舊版本,演示環境為windows的docker-desktop。

先安裝一下gitlab,這裏不推薦做掛載,在docker-desktop上會有文件讀寫的權限導致運行出問題。

docker run -d  -p 443:443 -p 80:80 -p 222:22 ^
--hostname mygitlab.local --name gitlab --restart always ^
gitlab/gitlab-ce:18.5.0-ce.0
在本地的C:\Windows\System32\drivers\etc目錄的hots下面提前配置一下域名,這是gitla安裝需要的: 127.0.0.1  mygitlab.local
然後可以使用 mygitlab.local登錄本地的git,默認的賬號是root,密碼看這裏

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_02

 
還有一個gitlab.rb文件,跟初始密碼是同一個目錄下,配置一下下面的變量

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_03

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_04

 
也可以使用下面命令拷貝出來改完後再拷貝進去然後重啓服務

docker cp gitlab:/etc/gitlab/gitlab.rb D:\work\docker/gitlab.rb 拷貝出來然後替換
docker cp D:\work\docker\gitlab.rb gitlab:/etc/gitlab/gitlab.rb
下面就是安裝runner,首先拿到需要注入到runner中的token

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_05

 下面就是啓動服務的命令:

docker run -d --name gitlab-runner ^
--restart always ^
-v d:/dwz/docker-volume/gitlab-runner/config:/etc/gitlab-runner ^
-v /var/run/docker.sock:/var/run/docker.sock ^
gitlab/gitlab-runner:v13.2.4

然後需要註冊一個runner,這裏的registration-token就是gitlab拷貝出來的,url也是gitlab的地址

docker exec -it gitlab-runner gitlab-runner register -n ^
--url http://172.17.0.2 ^
--registration-token Tca8wkxwbjswexxtE_ij ^
--executor docker ^
--description "Docker Runner" ^
--docker-image "sonarsource/sonar-scanner-cli:latest"

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_06

 

以上就是完整的gitlab和ci/cd的搭建了。注意一下docker中默認使用的網關bridge,否則都要指定一下同一個,如果網關gateway:172.17.0.2不一致就需要各種網絡假如等等操作,所以安裝制定好就行。上面的有默認就不需要額外配置。

下面繼續sonar安裝:

services:
  postgres:
    image: postgres:13
    container_name: postgres
    ports:
      - "15432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar
      POSTGRES_DB: sonar
    network_mode: bridge

  sonar:
    image: sonarqube:9.9-community
    container_name: sonar
    depends_on:
      - postgres
    ports:
      - "9000:9000"
    environment:
      SONARQUBE_JDBC_USERNAME: sonar
      SONARQUBE_JDBC_PASSWORD: sonar
      # 內部容器互訪請用服務名:port(不要用容器 IP)
      SONARQUBE_JDBC_URL: jdbc:postgresql://postgres:5432/sonar
    volumes:
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_conf:/opt/sonarqube/conf
    network_mode: bridge

volumes:
  postgres_data:
  sonarqube_extensions:
  sonarqube_logs:
  sonarqube_data:
  sonarqube_conf:

使用docker-compose 安裝完後需要手動配置一下數據庫相關,還是社區版的插件安裝配置等。首先安裝舊版本,最後再試試新版本。

第一個插件可以就可以將 sonarQube 的審查結果以評論的試發佈到 gitlab 上面

https://github.com/javamachr/sonar-gitlab-plugin

第二個插件可以實現增強 sonarQube 多分支包括MR的代碼檢測

https://github.com/mc1arke/sonarqube-community-branch-plugin
第一個插件就固定一個最新的,第二個需要根據鏡像版本來安裝對應的插件和配置了。

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_07

 

docker cp "D:\work\docker\sonar-gitlab-plugin-5.4.0.jar" 67ccc284b64a:/opt/sonarqube/extensions/plugins/    (67ccc284b64a  是容器名)
docker cp "D:\work\docker\sonarqube-community-branch-plugin-25.9.0.jar" 67ccc284b64a:/opt/sonarqube/extensions/plugins/    (67ccc284b64a  是容器名)

下面需要拷貝一下配置文件然後改好覆蓋進去:有五行改動,分別是數據庫的配置,和第二個插件。如果配置不對或者插件版本不對都會導致服務啓動不了。

docker cp 容器名:/opt/sonarqube/conf/sonar.properties "D:\work\docker\sonar.properties"

docker cp "D:\work\docker\sonar.properties" 容器名:/opt/sonarqube/conf/sonar.properties

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_08

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_09

 

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_10

 

sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
sonar.jdbc.url=jdbc:postgresql://172.17.0.4:5432/sonar
sonar.web.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.14.0.jar=web
sonar.ce.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.14.0.jar=ce

 

可以看到我這個文件的插件是針對老版本sonarqube:9.9-community的配置,而拷貝插件命令是最新版本的sonarqube:community的配置,最新版最後説。

下面就可以通過9000端口進入sonar了, 默認賬號密碼admin,需要進入後改掉密碼。

老版本比新版本多了這個分支管理功能

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_11

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_12

 
下面就是如何配置sonar和gitlab的交互了,這裏不配置gitlab可以通過sonar繼承登錄 和分組權限功能,直接最高權限來做配置。

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_13

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_14

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_15

 

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_16

 

上面權限看着勾選,前面幾個read少不了的。

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_17

 點擊創建項目會提示你輸入gitlab的personal access token,然後選擇要導入的項目到gitlab,然後就關聯上項目了。

 

在gitlab配置一下sonar的回調地址和權限即可,否則sonar拿不到runner掃描的結果

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_18

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_19

 

 

下面就可以配置項目的cicd的yml文件

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_20

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_21

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_22

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_23

 

上面的第一步需要.NET,第二步就是需要在gitlab配置兩個變量

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_24

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_25

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_26

 這裏都是按照sonar的步驟來創建SONAR_TOKEN變量和值,然後按照要求勾選Visibility,Flags。

下面截圖的gitlab的配置地址是sonar新的對外的ip沒改過來,實際是172.17.0.5

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_27

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_28

 

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_29

 上面的SONAR_TOKEN這裏的token來自

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_30

 或者來自下面

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_31

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_32

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_33

 


以上配置都完成了,下面就是在gitlab的項目中創建一個.gitlab-ci.yml文件,這個文件可以從sonar剛才的配置中拷貝也可以自己寫

image: mcr.microsoft.com/dotnet/sdk:8.0
variables:
  SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
  GIT_DEPTH: "0"
  JAVA_VERSION: "17"
  SONAR_PROJECT_KEY: "root_testsonar_AZqR29AXIQF2ktGMbFvi"
  SONAR_HOST_URL: "http://172.17.0.5:9000"

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'
    - if: '$CI_PIPELINE_SOURCE =~ /merge_request/'

stages:
  - sonar

sonar_scan:
  stage: sonar
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'
    - if: '$CI_PIPELINE_SOURCE =~ /merge_request/'
  before_script:
    - apt-get update && apt-get install -y --no-install-recommends openjdk-${JAVA_VERSION}-jdk
    - export JAVA_HOME=$(update-alternatives --query java | grep "Best" | awk '{print $5}' | sed 's/bin\/java//')
    - export PATH="$JAVA_HOME/bin:$PATH"
    - dotnet tool install --global dotnet-sonarscanner
    - export PATH="$PATH:$HOME/.dotnet/tools"
    - java -version
    - dotnet tool list -g
    - command -v dotnet-sonarscanner || true

  script:
    - |
      if [ -n "${CI_MERGE_REQUEST_IID}" ]; then
        # MR / Pull Request 分析
        dotnet sonarscanner begin \
          /k:"${SONAR_PROJECT_KEY}" \
          /d:sonar.host.url="${SONAR_HOST_URL}" \
          /d:sonar.token="${SONAR_TOKEN}" \
          /d:sonar.pullrequest.key="${CI_MERGE_REQUEST_IID}" \
          /d:sonar.pullrequest.branch="${CI_COMMIT_REF_NAME}" \
          /d:sonar.pullrequest.base="${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}" \
          /d:sonar.qualitygate.wait=true \
          /d:sonar.projectBaseDir="${CI_PROJECT_DIR}" \
          /d:sonar.exclusions="**/bin/**,**/obj/**,**/Properties/**"
      else
        # 普通分支(例如 main)分析
        dotnet sonarscanner begin \
          /k:"${SONAR_PROJECT_KEY}" \
          /d:sonar.host.url="${SONAR_HOST_URL}" \
          /d:sonar.token="${SONAR_TOKEN}" \
          /d:sonar.branch.name="${CI_COMMIT_BRANCH}" \
          /d:sonar.qualitygate.wait=true \
          /d:sonar.projectBaseDir="${CI_PROJECT_DIR}" \
          /d:sonar.exclusions="**/bin/**,**/obj/**,**/Properties/**"
      fi
    - dotnet build --configuration Release
    - dotnet sonarscanner end /d:sonar.token="${SONAR_TOKEN}"

  allow_failure: false
  cache:
    paths:
      - ${SONAR_USER_HOME}
      - $HOME/.dotnet/tools

 

sonarqube-check:
  image: mcr.microsoft.com/dotnet/core/sdk:latest
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
    GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script: 
      - "apt-get update"
      - "apt-get install --yes openjdk-11-jre"
      - "dotnet tool install --global dotnet-sonarscanner"
      - "export PATH=\"$PATH:$HOME/.dotnet/tools\""
      - "dotnet sonarscanner begin /k:\"root_testforsonar_AZpytHmBvMocvQWN9yIR\" /d:sonar.login=\"$SONAR_TOKEN\" /d:\"sonar.host.url=$SONAR_HOST_URL\" "
      - "dotnet build"
      - "dotnet sonarscanner end /d:sonar.login=\"$SONAR_TOKEN\""
  allow_failure: true
  only:
    - main

以上都可以,經供參考
只有一點注意:

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_34

 

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_35

 上面的這個SONAR_PROJECT_KEY來自於

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_java_36

 

然後提交和並請求(哪裏觸發代碼審查可以根據yml文件配置寫的來)會掃描代碼,展示代碼問題了

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_git_37

 

下面是最新的sonar的安裝

docker exec -it postgres psql -U sonar -c "CREATE DATABASE sonar2;"

docker run -d ^
  --name sonar2 ^
  --network bridge ^
  -p 9001:9000 ^
  -e SONARQUBE_JDBC_URL=jdbc:postgresql://postgres:5432/sonar2 ^
  -e SONARQUBE_JDBC_USERNAME=sonar ^
  -e SONARQUBE_JDBC_PASSWORD=sonar ^
  -v sonarqube2_extensions:/opt/sonarqube/extensions ^
  -v sonarqube2_logs:/opt/sonarqube/logs ^
  -v sonarqube2_data:/opt/sonarqube/data ^
  -v sonarqube2_conf:/opt/sonarqube/conf ^
  sonarqube:community

 

最新版本的sonar沒有分支管理功能,只能查看一個分支的掃描統計,gitlab評論展示功能不變,配置好對應版本插件就行。

基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_38

 


基於GitLab+SonarQube 搭建自動化代碼檢測平台_gitlab sonar_docker_39