SonarQube:持续代码质量与安全扫描

FreeGuideOnline 最新 2026-07-04

bash docker run -d --name sonarqube
-p 9000:9000
-e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true
sonarqube:lts-community


> **说明**:`-e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true` 是避免某些环境下 Elasticsearch 内存检查失败。生产环境请勿使用此参数,而是通过 `-e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true` 配置合理的内核参数。

### 步骤2:访问 Web UI

容器启动需要几分钟,等待日志出现 “SonarQube is operational” 后,访问 `http://localhost:9000`。默认账号密码为 `admin` / `admin`,首次登录后会强制修改密码。

### 步骤3:创建本地项目并生成令牌

登录后,你可以选择手动创建项目或稍后在扫描时自动创建。推荐流程:

1. 点击顶部导航 “Projects” -> “Create Project”。
2. 输入项目显示名称和项目标识符(Key),点击 “Set Up”。
3. 在 “Provide a token” 步骤,选择 “Generate a token”,输入令牌名称(如 `my-local-token`),点击 “Generate” 并**立即复制保存**,这个令牌只显示一次。
4. 继续,选择项目的主要语言和构建技术(如 Maven、Gradle、Other(JS/TS)等),页面会给出具体的扫描命令,后面会用到。

## 执行第一次代码扫描

SonarQube 的扫描是通过扫描器(Scanner)完成的。扫描器在客户端运行,分析代码后将结果推送到 SonarQube 服务器。

### 对于通用项目使用 SonarScanner CLI

这是最灵活的方式,适用于几乎所有语言。

#### 1. 下载并配置 Scanner

从 [SonarScanner CLI 下载页面](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/) 获取对应操作系统的压缩包,解压后将其 `bin` 目录添加到系统 PATH 中。

你也可以使用 Docker 一键扫描(无需本地安装):

```bash
docker run \
  --rm \
  --network host \
  -e SONAR_HOST_URL="http://localhost:9000" \
  -e SONAR_TOKEN="你的项目令牌" \
  -v "你的项目绝对路径:/usr/src" \
  sonarsource/sonar-scanner-cli

2. 在项目根目录创建 sonar-project.properties

如果你想手动配置扫描参数,可以创建此文件:

# 必须唯一,对应 SonarQube 中项目的 Key
sonar.projectKey=my-awesome-project
# 项目名称,在 UI 中显示
sonar.projectName=My Awesome Project
# 项目版本
sonar.projectVersion=1.0

# 源码目录,逗号分隔多个路径
sonar.sources=src
# 编译后的 class 文件目录(Java 等需要)
sonar.java.binaries=target/classes

# 排除某些文件
sonar.exclusions=**/test/**, **/*.spec.ts

# 编码格式
sonar.sourceEncoding=UTF-8

3. 运行扫描命令

在项目根目录下执行:

sonar-scanner \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=你的项目令牌

或者如果已有属性文件,且环境变量已设置:

export SONAR_HOST_URL=http://localhost:9000
export SONAR_TOKEN=你的令牌
sonar-scanner

扫描完成后,回到 SonarQube Web UI,刷新项目页,你就能看到详细的代码质量报告。

对于 Maven/Gradle 项目的一键扫描

如果使用构建工具,集成更简单,无需单独下载 Scanner。

Maven 项目:

确保 mvn 命令可用,在项目根目录执行:

mvn clean verify sonar:sonar \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=你的令牌

Gradle 项目:

build.gradle 中添加插件:

plugins {
  id "org.sonarqube" version "4.4.1.3373"
}

然后运行:

gradle sonarqube \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=你的令牌

读懂 SonarQube 报告与质量门

扫描后的仪表板是核心,理解这些指标才能让 SonarQube 发挥作用。

整体质量视图

进入项目主页,你会看到几个关键块:

  • 质量门状态:绿色通过(Passed)或红色失败(Failed)。如果配置了条件并失败,说明代码未达到标准。
  • Bug & 漏洞:显示静态分析发现的错误和安全风险数量,按严重程度着色。
  • 代码异味:与可维护性相关的问题,右侧会估算“技术债务”时间。例如 “10h” 表示修复所有异味预计需要 10 小时。
  • 覆盖率:显示由单元测试覆盖的代码行百分比。如果未集成测试报告,则为 0% 或 N/A。
  • 重复:重复代码块的百分比。通常建议保持在 3% 以下。
  • 代码行数、复杂度等统计信息。

深入问题列表

点击 “Issues” 标签,你可以看到所有检测出的问题列表。这里可以进行高级筛选:

  • 严重级别:Blocker(阻断)、Critical(严重)、Major(主要)、Minor(次要)、Info(提示)。
  • 类型:Bug、Vulnerability、Code Smell。
  • 状态:Open(未解决)、Confirmed(已确认)、False Positive(误报)、Won't Fix(不予修复)。
  • 指派:可以将问题分配给具体开发者。
  • 标签:按规则分类(如 cwe, security, performance)。

点击具体问题,右侧会显示详细说明、所在代码位置,以及为什么这是一个问题、如何修复,甚至给出符合规则的代码示例。这是新手学习和团队规范统一的绝佳资源。

自定义质量门

默认的质量门 “Sonar way” 是官方推荐的起点。你可以创建自己的质量门以匹配团队标准。

  1. 顶部导航点击 “Quality Gates”,然后点击 “Create”。
  2. 输入名称(如 “My strict gate”),点击“Add Condition”。
  3. 选择指标,例如:
    • On New Code(推荐,只关注新增代码的质量,避免历史债务干扰)
      • Coverage:新代码覆盖率小于 80% 则标记失败。
      • Blocker Issues:新代码阻断问题 > 0 则失败。
    • Overall Code(全局代码)
      • Technical Debt Ratio:技术债务比率超过 5% 失败。
  4. 将项目添加到该质量门下,在质量门设置页面点击 “Projects” 选项卡,添加到指定项目。

与 CI/CD 集成:自动化质量保障

将 SonarQube 扫描融入流水线,才能真正实现“持续”质量检查。以下以 GitLab CI 和 GitHub Actions 为例。

GitLab CI 集成示例

.gitlab-ci.yml 中加入扫描步骤:

stages:
  - test
  - sonarqube-check

sonarqube-check:
  stage: sonarqube-check
  image: 
    name: sonarsource/sonar-scanner-cli:latest
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # 防止缓存冲突
    GIT_DEPTH: "0"  # 完整 git 历史获取,用于新代码分析
  script:
    - sonar-scanner
      -Dsonar.projectKey=$CI_PROJECT_NAME
      -Dsonar.sources=.
      -Dsonar.host.url=$SONAR_HOST_URL
      -Dsonar.token=$SONAR_TOKEN
  allow_failure: true  # 或 false,取决于你是否要阻断流水线

注意:需要在 GitLab 项目的 CI/CD 变量中设置 SONAR_HOST_URLSONAR_TOKEN

GitHub Actions 示例

在仓库的 .github/workflows/sonarqube.yml 中:

name: SonarQube Scan
on:
  push:
    branches: [ main ]
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  sonarqube:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: SonarQube Scan
        uses: SonarSource/sonarqube-scan-action@v2
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}

使用官方的 GitHub Action,无需手动安装 Scanner。同样配置 Secrets。

提升扫描价值:集成测试覆盖率与外部报告

只进行静态分析还不够,结合测试覆盖率才能全面衡量。

集成 JaCoCo(Java)报告

Maven 项目通常使用 JaCoCo 插件生成报告:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

然后执行 mvn clean verify,报告默认生成在 target/site/jacoco/jacoco.xml。你在执行 sonar:sonar 时,需要设置参数指向报告:

mvn sonar:sonar \
  -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml

集成 JavaScript/TypeScript 覆盖率(Istanbul)

如果你使用 Jest 或类似测试框架,先确保配置生成 lcov.info 格式的报告。在 package.json 中配置 Jest:

{
  "jest": {
    "collectCoverage": true,
    "coverageReporters": ["lcov"]
  }
}

然后在 sonar-project.properties 中指定路径:

sonar.javascript.lcov.reportPaths=coverage/lcov.info

集成第三方安全报告(可选)

SonarQube 还能导入其他安全工具的 SARIF 报告,通过 sonar.externalIssuesReportPaths 属性集成,例如:

sonar.externalIssuesReportPaths=bandit-report.json,eslint-report.json