Mac M1 Docker + Sonarqube 服务部署 分析Swift项目代码

1,008 阅读11分钟

这篇文章,主要是介绍如何在M1机器上来通过Docker工具来部署Sonarqube服务,在开始部署之前,我们先来了解SonarQube的作用

SonarQube介绍

SonarQube 是一款开源的代码质量管理平台,旨在帮助开发团队分析代码并持续改进代码质量和安全性。它通过静态代码分析工具对项目中的代码进行全面的检查,提供关于代码质量、技术债务、潜在安全漏洞等多方面的反馈。

核心功能

  1. 代码质量分析

    1. 检查代码中的问题,如重复代码、潜在错误、代码复杂度过高等。
    2. 支持多种编程语言,包括 Java、C、C++、C#、Python、JavaScript、Swift 等。
  2. 安全漏洞检测

    1. 检测代码中的安全漏洞和漏洞风险,例如 SQL 注入、跨站脚本攻击 (XSS) 等问题。
  3. 技术债务管理

    1. 提供技术债务的量化视图,帮助团队了解为了提高代码质量需要进行多少改动。
  4. 报告生成与趋势分析

    1. 可视化展示代码质量历史趋势,便于跟踪改进进展。
  5. CI /CD 集成

    1. 支持与 Jenkins、GitLab CI/CD、Azure DevOps 等集成,自动化分析代码。
  6. 质量门槛 (Quality Gates)

    1. 定义项目是否满足代码质量标准的规则,确保项目未通过质量检查时不能上线。

优点

  1. 开源且免费(企业版提供更多高级功能)。
  2. 支持多语言和多框架
  3. 易于与现有开发工具链集成
  4. 提供全面的代码质量和安全性反馈

缺点

  1. 学习成本高: 配置和规则定制需要一定的学习成本。
  2. 机器性能要求严格: 对大规模代码库分析时可能需要较高的硬件性能。
  3. 规则配置过于严格: 如果规则配置不当,可能会导致很多误报,增加开发人员的负担。

大概了解了SonarQube的作用,接下来我们在M1的机器上来部署SonarQube服务。这里我们采用从 Docker镜像安装 SonarQube 服务器的开发者版

为什么采用Docker来安装,因为本地安装我没有成功,有很多java jdk环境配置的坑

Q:为什么不用社区免费版本?

A:因为我们要检测的工程编程语言是Swift, 社区的免费版本不支持,所以我们通过申请14天免费试用,尝试一下。

Docker环境安装教程

下载安装

现在Docker的安装比较简单,根据官方安装教程:Install Docker Desktop on Mac,来一步步安装,这里我的电脑是M1,所以选择苹果芯片Apple Silicon或安装包下载。

按照步骤安装好之后,打开Docker应用程序,出现如下界面:

配置 Docker 镜像加速

国内镜像地址

修改 Docker 配置文件

我这里配置了很多镜像源, 总有一款适合你,修改配置文件如下:

  "registry-mirrors": [
    "https://dhub.kubesre.xyz",
    "https://docker.chenby.cn",
    "https://docker.1panel.live",
    "https://docker.anyhub.us.kg",
    "https://dockerpull.com",
    "https://hub.rat.dev",
    "https://docker.m.daocloud.io"
  ]

按照上图的位置,点击右上角的设置,选择Docker Engine,在当前的json文件下添加上面的镜像源即可。

尝试一下

打开一个命令行窗口,输入docker --version, 会显示当前Docker安装版本。

docker --version

接着输入以下命令,来测试Docker是否可以正常运行

 docker run -d -p 8080:80 docker/welcome-to-docker

输入一下命令后,终端会提示没有找到welcome-to-docker镜像,接着去下载,具体内容如下:

这个时候我们打开Docker,进入Image和Container选项:

可以看到镜像已经下载完成,并且容器处于运行状态,当我们访问http://localhost:8080/,会出现如下界面,就说明Docker已经安装完毕。

Sonarqube 服务搭建

首先我们按照官方的教程macOS 系统上的预安装步骤,来做一些前置配置。在终端运行以下命令:

sudo sysctl kern.maxfiles=131072
sudo sysctl kern.maxfilesperproc=131072
ulimit -n 131072

接着我们使用Docker compose 来安装和配置sonar镜像 以及数据库镜像

我采用了单独安装sonar 和单独安装数据库,但是很不幸我失败了,只能通过内嵌数据库方式来

docker-compose.yml文件配置

使用 Docker compose 启动容器非常简单,我们首先需要添加一个docker-compose.yml配置文件

具体的配置文件参考官方提供的docker-compose.yml配置规范,下面是我成功启动服务的配置,大家也可以直接复制。

services:
  sonarqube:
    image: sonarqube: 10.8 -developer
    container_name: sonarqube
    restart: 'no'
    networks:
      - sonarnet
    environment:
      - sonar.jdbc.username=sonar
      - sonar.jdbc.password=sonar
      - sonar.jdbc.url=jdbc:postgresql://sonarqube-postgre:5432/sonarqube
      - sonar.search.javaOpts=-Xms256m -Xmx256m
    ports:
      - 9000:9000
    depends_on:
      - sonarqube-postgre
    links:
      - sonarqube-postgre
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
      - sonarqube_temp:/opt/sonarqube/temp

  sonarqube-postgre:
    image: postgres:15
    container_name: sonarqube-postgre
    restart: 'no'
    networks:
        - sonarnet
    environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
      - POSTGRES_DB=sonarqube
    volumes:
      - sonarqube_postgre_db:/var/lib/postgresql
      - sonarqube_postgre_data:/var/lib/postgresql/data
    ports:
      - 5432:5432

volumes:
  sonarqube_data:
  sonarqube_temp:
  sonarqube_extensions:
  sonarqube_logs:
  sonarqube_postgre_db:
  sonarqube_postgre_data:

networks:
  sonarnet:
    driver: bridge

我来具体介绍下上面的配置文件

Services 部分

SonarQube 服务 ( sonarqube )
  • image: sonarqube:10.8-developer 指定要使用的 SonarQube 镜像版本 (10.8-developer)。这是开发者版。

  • container_name: sonarqube 为容器命名为 sonarqube,方便通过容器名称直接操作。

  • restart: 'no' 指定在容器停止后不自动重启。生产环境建议配置为 alwaysunless-stopped

  • networks: sonarnet 将容器加入 sonarnet 网络,方便与其他服务(如 PostgreSQL)通信。

  • environment 环境变量

    • **sonar.jdbc.username=sonar**数据库用户名为 sonar
    • **sonar.jdbc.password=sonar**数据库密码为 sonar
    • sonar.jdbc.url=jdbc:postgresql://sonarqube-postgre:5432/sonarqube 数据库的连接 URL,指向服务名为 sonarqube-postgre 的 PostgreSQL 容器。
    • sonar.search.javaOpts=-Xms256m -Xmx256m 配置 JVM 搜索组件的内存使用,最小和最大内存为 256 MB
  • ports: 9000:9000 将宿主机的 9000 端口映射到容器的 9000 端口,SonarQube 的 Web 服务将在 http://localhost:9000 上可用。

  • depends_on: sonarqube-postgre 确保 PostgreSQL 服务 sonarqube-postgre 在 SonarQube 服务启动之前已运行。

  • links: sonarqube-postgre 将 PostgreSQL 服务链接到 SonarQube,主要是历史配置,用于明确网络通信。

  • volumes 数据卷

    • sonarqube_data:/opt/sonarqube/data 存储 SonarQube 的数据。
    • sonarqube_extensions:/opt/sonarqube/extensions 存储插件等扩展文件。
    • sonarqube_logs:/opt/sonarqube/logs 存储日志文件。
    • sonarqube_temp:/opt/sonarqube/temp 存储临时文件。
PostgreSQL 服务 ( sonarqube-postgre )
  • image: postgres:15 使用 PostgreSQL 15 版本镜像。

  • container_name: sonarqube-postgre 为容器命名为 sonarqube-postgre

  • restart: 'no' 容器停止后不自动重启。

  • networks: sonarnet 将容器加入 sonarnet 网络,与 SonarQube 容器通信。

  • environment 环境变量

    • POSTGRES_USER=sonar 创建数据库用户 sonar
    • POSTGRES_PASSWORD=sonar 用户 sonar 的密码为 sonar
    • POSTGRES_DB=sonarqube 初始化数据库名称为 sonarqube
  • volumes 数据卷

    • sonarqube_postgre_db:/var/lib/postgresql 存储 PostgreSQL 的数据库主文件。
    • sonarqube_postgre_data:/var/lib/postgresql/data 存储 PostgreSQL 的数据文件。
  • ports: 5432:5432 将宿主机的 5432 端口映射到容器的 5432 端口,PostgreSQL 可通过 localhost:5432 访问。

Volumes 部分

用于数据持久化的 Docker 卷,确保容器停止或重启后,数据不会丢失:

  • sonarqube_data:SonarQube 的数据存储。
  • sonarqube_temp:SonarQube 的临时数据。
  • sonarqube_extensions:SonarQube 的插件或扩展。
  • sonarqube_logs:SonarQube 的日志文件。
  • sonarqube_postgre_db sonarqube_postgre_data:PostgreSQL 的数据库文件和数据存储。

Networks 部分

定义一个名为 sonarnet 的 Docker 网络:

  • driver: bridge:使用 bridge 网络驱动,容器通过虚拟网桥通信。

Sonar 服务启动

通过以上的方式安装,我们只需要在该配置文件的同级目录下,执行以下命令,即可在Docker里同时下载sonar 和pgsql 两个镜像并启动这两个容器。

docker compose up -d
  1. docker compose up

    1. 作用:根据当前目录下的 docker-compose.yml 文件,创建并启动文件中定义的所有服务(即容器、网络、卷等)。

    2. 主要任务

      • 如果镜像不存在,会自动构建或拉取镜像。
      • 创建服务所需的容器。
      • 挂载卷、配置网络等。
      • 启动容器。
  2. -d

    1. 含义:代表 detached mode,即以“后台运行”模式启动容器。

    2. 效果

      • 容器在后台运行,命令行不会被阻塞。
      • 启动后,命令行可以继续执行其他操作。
    3. 如果省略 -d,容器会在前台运行,日志会直接输出到命令行。

通过这种配置文件的方式,即不需要你本地安装PostgreSQL, 也不需要你去创建数据库以及配置jdk环境。省心!!!

运行上面的命令启动服务后,我们可以在Docker的程序中看到相关的容器启动,和上面刚安装Docker启动第一个容器时一样。

可以看到sonar的服务已经启动,这个时候,我们就可以访问http://localhost:9000/,进入下面的界面,初始账号和密码都是**admin。**

输入后点击登录会要求你更改密码,这里我遇到了一个坑,当你在resetpassword输入框准备输入时就会得到如下提示:

解决方案是通过命令行注入新密码

curl -vu admin:admin -X POST "http://localhost:9000/api/users/change_password?login=admin&previousPassword=admin&password=MyNewPassword"

接下来我们就正式进入了sonar 本地服务网站

由于我们使用的是开发版,所以这里要求我们填写许可证,我们可以通过sonarqube官方网站发邮件申请一个14天免费试用的key。

代码分析

在进行代码分析之前,我们先需要先安装好环境及配置文件。

SonarScanner CLI 安装

首先我们需要安装 Sonarqube scanner

SonarQube ScannerSonarQube 的命令行工具,负责在项目代码中执行静态代码分析并将结果发送到 SonarQube 服务器。它是整个 SonarQube 系统的一个重要组成部分,主要用于在构建管道或本地环境中进行代码质量扫描。

这里我没有按照官方安装SonarScanner CLI的文档来,我使用下面的命令来安装

brew install sonar-scanner

这里只是安装步骤没有按照官方文档,但是项目配置还是需要参照文档的

配置本地项目

接下来我们下载官方提供的示例

git clone https://github.com/SonarSource/sonar-scanning-examples.git
cd sonar-scanning-examples

下载完成后,根据官方文档的项目配置在项目的根目录中创建一个名为的配置文件 sonar-project.properties

sonar-project.properties 具体内容如下:

sonar.projectKey=swift-coverage-example
sonar.projectName=swift-coverage-example
sonar.projectVersion=1.0
sonar.language=swift
sonar.sources=swift-coverage-example

# sonar.projectKey:项目的唯一标识符,需在 SonarQube 上预先配置。
# sonar.host.url:SonarQube 服务器的 URL(例如 http://localhost:9000)。
# sonar.sources:需要扫描的源代码目录。
# sonar.exclusions:需要排除的文件或目录。
# sonar.login:用于认证的访问令牌或用户名。

项目创建

安装好扫描仪,准备好要分析的本地项目之后,我们在Sonar本地服务上创建一个项目,在Projects > Create Project > Local project

我们创建一个本地项目swift-coverage-example

创建好之后,我们选择本地项目

接着生成该项目分析所需要的token

可以看到,这里已经给我们生成好了执行代码分析的命令:

sonar-scanner \
  -Dsonar.projectKey=swift-coverage-example \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=sqp_08ad39e25767fb99aa1e506e068179b2b95b16b3

分析结果

screenshot-20250102-164819.png

针对代码清洁部分和SwiftLint的对比

项目:TestProject 分支:dev

本地swiftlint 配置文件

image.png

Sonar 针对Swift语言的规则:rules.sonarsource.com/swift/

通过查看上面简单对比和规则的对比,可以看到Sonar里的规则和swiftlint的部分规则是重复的,双方都可以检测出,但是不重复的规则,双方检测结果也不一样,有的问题Sonar规则可以体现出来,有的问题swiftlint可以体现出来。具体要看规则的定制。

不过总体来说,相对于Swiftlint的单一检测,Sonar除了规则之外还有提供了很多其他的代码检测工具以及代码优化建议,同时他也支持在分析的时候传入Swiftlint的分析报告,并一同展示在服务器上。

导出分析报告

PDF reports | SonarQube Server Documentation

可以导出PDF报告,不过,需要企业版......

  1. Docker的镜像源一定要配置正确,否则后面的操作无法进行
  2. 第一次登录成功后会提示修改密码,在修改密码框输入时会提示组件加载错误

解决方案:

stackoverflow.com/questions/6…

我采用的是是最佳答案,直接通过命令行注入新密码

curl -vu admin:admin -X POST "http://localhost:9000/api/users/change_password?login=admin&previousPassword=admin&password=MyNewPassword"

3. 你可以尝试使用费compose的方式来启动sonar服务,是可以启动成功,但是会一直提示,我没有解决,也没有从社区找到解决方案。