JAVA

使用docker 搭建 SonarQube 代码质量管理平台

一、概述


Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从多个维度检测代码质量,通过插件形式,可以支持包括java、python、C#、go、scala、kotlin、JavaScrip、Groovy等二十几种编程语言的代码质量管理与检测。

下面使用docker 启动一个 sonarqube , 便于快速体验此平台提供的功能。

二、安装 SonarQube


你可以下载zip文件的传统方式安装SonarQube,也可以使用docker 镜像的方式启动 SonarQube容器。

1、 下载zip文件安装SonarQube https://www.sonarqube.org/downloads/

  • 下载上图中的zip文件
  • 解压缩zip文件,例如在C:\ sonarqube或/ opt / sonarqube中
  • 运行下面的命令启动 SonarQube Server
# 在windows中,执行如下命令
C:\sonarqube\bin\windows-x86-64\StartSonar.bat

# 在linux等其他系统中执行如下命令
/opt/sonarqube/bin/[OS]/sonar.sh console

2、使用docker 安装 SonarQube

  • 在docker hub 中找到 sonarqube
  • 使用 docker pull sonarqube 拉取镜像
  • 运行下面的命令启动 SonarQube Server
docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latest

3、登录SonarQube Server

实例启动并运行后,使用系统管理员凭据登录到 http://localhost:9000

  • 用户名:admin
  • 密码:admin

登录成功后需要重置密码

三、分析项目


登录成功后,如下图所示:

1、安装中文包

中文包安装成功后如下图

2、分析项目

  • 单击创建新项目按钮。
  • 给您的项目一个项目键和一个显示名称,然后单击设置按钮。
  • 在“提供令牌”下,选择“生成令牌”。为您的令牌命名,点击生成按钮,然后点击继续。
  • 在“对项目运行分析”下选择项目的主要语言,然后按照说明分析项目。在这里,您将在代码上下载并执行扫描程序(如果您使用的是Maven或Gradle,则会自动下载该扫描程序)。
  • 使用Maven执行SonarQube分析是非常简单的。只需要在你的项目目录下执行如下命令。
mvn sonar:sonar \
  -Dsonar.projectKey=test \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=a98ea942c2c4bd02b1621ee26653fe1b7007d83d
  • 分析完成后,页面会自动刷新,您将在SonarQube上看到第一个分析:

四、遇到的问题


①执行上面的mvn命令,出现如下问题:

[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.8.0.2131:sonar (default-cli) on project quarkus-demo: Your project contains .java files, please provide
 compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property.

原因:项目只包含 .java 文件,没有编译成 .class 文件
解决:需要编译先项目,先执行 mvn pakage 再执行 mvn sonar: sonar ,也可以合并执行下面的命令

mvn package sonar:sonar \
  -Dsonar.projectKey=test \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=a98ea942c2c4bd02b1621ee26653fe1b7007d83d

②执行上面的mvn命令,出现如下问题:

[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.7.0.1746:sonar (default-cli) on project mail-service: Not authorized. Please check the properties sonar.login and sonar.password. -> [Help 1]

报错原因是缺少用户密码,增加 -D”sonar.password=123456″ 参数,具体命令如下:

mvn clean verify sonar:sonar \
  -Dsonar.projectKey=mail-service \
  -Dsonar.projectName='mail-service' \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=admin \
  -Dsonar.password=xxxx

③使用的镜像:sonarqube:lastest / sonarqube:9.8-community ,9.x 版本应该都会报错

启动命令(只是为了看能都启动成功) docker run sonarqube

报错如下:

2023.02.04 01:55:35 INFO app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /opt/sonarqube/temp
2023.02.04 01:55:35 INFO app[][o.s.a.es.EsSettings] Elasticsearch listening on [HTTP: 127.0.0.1:9001, TCP: 127.0.0.1:36696]
2023.02.04 01:55:35 INFO app[][o.s.a.ProcessLauncherImpl] Launch process[ELASTICSEARCH] from [/opt/sonarqube/elasticsearch]: /opt/sonarqube/elasticsearch/bin/elasticsearch
could not find java in ES_JAVA_HOME at /usr/lib/jvm/java-17-openjdk/bin/java
2023.02.04 01:55:35 WARN app[][o.s.a.p.AbstractManagedProcess] Process exited with exit value [ElasticSearch]: 1
2023.02.04 01:55:35 INFO app[][o.s.a.SchedulerImpl] Process[ElasticSearch] is stopped
2023.02.04 01:55:35 INFO app[][o.s.a.SchedulerImpl] Waiting for Elasticsearch to be up and running
2023.02.04 01:55:35 INFO app[][o.s.a.SchedulerImpl] SonarQube is stopped 

问题排查:

  • 1:docker run -it sonarqube /bin/bash 进入镜像内部查看环境变量 JAVA_HOME 没问题
  • 2:查看 jdk的权限设置,是不是es的启动用户看不到,发现也是正常的
  • 3:想不出来其他的,9.x之前的镜像是没有问题的,于是百度

官方解决方案:could not find java in ES_JAVA_HOME at /opt/java/openjdk/bin/java · Issue #494 · SonarSource/docker-sonarqube · GitHub

原来是9.x 的镜像并没有处理linux的系统方案安全配置,需要我们手动配置

处理:

配置文件下载地址:https://github.com/moby/moby/blob/master/profiles/seccomp/default.json

命令:

docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 --security-opt=seccomp=/mnt/sonar/seccomp_profile.json sonarqube:latest

如果大家看不到,直接复制如下文件即可

{
    "defaultAction": "SCMP_ACT_TRACE",
    "defaultErrnoRet": 1,
    "archMap": [
        {
            "architecture": "SCMP_ARCH_X86_64",
            "subArchitectures": [
                "SCMP_ARCH_X86",
                "SCMP_ARCH_X32"
            ]
        },
        {
            "architecture": "SCMP_ARCH_AARCH64",
            "subArchitectures": [
                "SCMP_ARCH_ARM"
            ]
        },
        {
            "architecture": "SCMP_ARCH_MIPS64",
            "subArchitectures": [
                "SCMP_ARCH_MIPS",
                "SCMP_ARCH_MIPS64N32"
            ]
        },
        {
            "architecture": "SCMP_ARCH_MIPS64N32",
            "subArchitectures": [
                "SCMP_ARCH_MIPS",
                "SCMP_ARCH_MIPS64"
            ]
        },
        {
            "architecture": "SCMP_ARCH_MIPSEL64",
            "subArchitectures": [
                "SCMP_ARCH_MIPSEL",
                "SCMP_ARCH_MIPSEL64N32"
            ]
        },
        {
            "architecture": "SCMP_ARCH_MIPSEL64N32",
            "subArchitectures": [
                "SCMP_ARCH_MIPSEL",
                "SCMP_ARCH_MIPSEL64"
            ]
        },
        {
            "architecture": "SCMP_ARCH_S390X",
            "subArchitectures": [
                "SCMP_ARCH_S390"
            ]
        },
        {
            "architecture": "SCMP_ARCH_RISCV64",
            "subArchitectures": null
        }
    ],
    "syscalls": [
        {
            "names": [
                "accept",
                "accept4",
                "access",
                "adjtimex",
                "alarm",
                "bind",
                "brk",
                "capget",
                "capset",
                "chdir",
                "chmod",
                "chown",
                "chown32",
                "clock_adjtime",
                "clock_adjtime64",
                "clock_getres",
                "clock_getres_time64",
                "clock_gettime",
                "clock_gettime64",
                "clock_nanosleep",
                "clock_nanosleep_time64",
                "close",
                "close_range",
                "connect",
                "copy_file_range",
                "creat",
                "dup",
                "dup2",
                "dup3",
                "epoll_create",
                "epoll_create1",
                "epoll_ctl",
                "epoll_ctl_old",
                "epoll_pwait",
                "epoll_pwait2",
                "epoll_wait",
                "epoll_wait_old",
                "eventfd",
                "eventfd2",
                "execve",
                "execveat",
                "exit",
                "exit_group",
                "faccessat",
                "faccessat2",
                "fadvise64",
                "fadvise64_64",
                "fallocate",
                "fanotify_mark",
                "fchdir",
                "fchmod",
                "fchmodat",
                "fchown",
                "fchown32",
                "fchownat",
                "fcntl",
                "fcntl64",
                "fdatasync",
                "fgetxattr",
                "flistxattr",
                "flock",
                "fork",
                "fremovexattr",
                "fsetxattr",
                "fstat",
                "fstat64",
                "fstatat64",
                "fstatfs",
                "fstatfs64",
                "fsync",
                "ftruncate",
                "ftruncate64",
                "futex",
                "futex_time64",
                "futex_waitv",
                "futimesat",
                "getcpu",
                "getcwd",
                "getdents",
                "getdents64",
                "getegid",
                "getegid32",
                "geteuid",
                "geteuid32",
                "getgid",
                "getgid32",
                "getgroups",
                "getgroups32",
                "getitimer",
                "getpeername",
                "getpgid",
                "getpgrp",
                "getpid",
                "getppid",
                "getpriority",
                "getrandom",
                "getresgid",
                "getresgid32",
                "getresuid",
                "getresuid32",
                "getrlimit",
                "get_robust_list",
                "getrusage",
                "getsid",
                "getsockname",
                "getsockopt",
                "get_thread_area",
                "gettid",
                "gettimeofday",
                "getuid",
                "getuid32",
                "getxattr",
                "inotify_add_watch",
                "inotify_init",
                "inotify_init1",
                "inotify_rm_watch",
                "io_cancel",
                "ioctl",
                "io_destroy",
                "io_getevents",
                "io_pgetevents",
                "io_pgetevents_time64",
                "ioprio_get",
                "ioprio_set",
                "io_setup",
                "io_submit",
                "io_uring_enter",
                "io_uring_register",
                "io_uring_setup",
                "ipc",
                "kill",
                "landlock_add_rule",
                "landlock_create_ruleset",
                "landlock_restrict_self",
                "lchown",
                "lchown32",
                "lgetxattr",
                "link",
                "linkat",
                "listen",
                "listxattr",
                "llistxattr",
                "_llseek",
                "lremovexattr",
                "lseek",
                "lsetxattr",
                "lstat",
                "lstat64",
                "madvise",
                "membarrier",
                "memfd_create",
                "memfd_secret",
                "mincore",
                "mkdir",
                "mkdirat",
                "mknod",
                "mknodat",
                "mlock",
                "mlock2",
                "mlockall",
                "mmap",
                "mmap2",
                "mprotect",
                "mq_getsetattr",
                "mq_notify",
                "mq_open",
                "mq_timedreceive",
                "mq_timedreceive_time64",
                "mq_timedsend",
                "mq_timedsend_time64",
                "mq_unlink",
                "mremap",
                "msgctl",
                "msgget",
                "msgrcv",
                "msgsnd",
                "msync",
                "munlock",
                "munlockall",
                "munmap",
                "nanosleep",
                "newfstatat",
                "_newselect",
                "open",
                "openat",
                "openat2",
                "pause",
                "pidfd_open",
                "pidfd_send_signal",
                "pipe",
                "pipe2",
                "pkey_alloc",
                "pkey_free",
                "pkey_mprotect",
                "poll",
                "ppoll",
                "ppoll_time64",
                "prctl",
                "pread64",
                "preadv",
                "preadv2",
                "prlimit64",
                "process_mrelease",
                "pselect6",
                "pselect6_time64",
                "pwrite64",
                "pwritev",
                "pwritev2",
                "read",
                "readahead",
                "readlink",
                "readlinkat",
                "readv",
                "recv",
                "recvfrom",
                "recvmmsg",
                "recvmmsg_time64",
                "recvmsg",
                "remap_file_pages",
                "removexattr",
                "rename",
                "renameat",
                "renameat2",
                "restart_syscall",
                "rmdir",
                "rseq",
                "rt_sigaction",
                "rt_sigpending",
                "rt_sigprocmask",
                "rt_sigqueueinfo",
                "rt_sigreturn",
                "rt_sigsuspend",
                "rt_sigtimedwait",
                "rt_sigtimedwait_time64",
                "rt_tgsigqueueinfo",
                "sched_getaffinity",
                "sched_getattr",
                "sched_getparam",
                "sched_get_priority_max",
                "sched_get_priority_min",
                "sched_getscheduler",
                "sched_rr_get_interval",
                "sched_rr_get_interval_time64",
                "sched_setaffinity",
                "sched_setattr",
                "sched_setparam",
                "sched_setscheduler",
                "sched_yield",
                "seccomp",
                "select",
                "semctl",
                "semget",
                "semop",
                "semtimedop",
                "semtimedop_time64",
                "send",
                "sendfile",
                "sendfile64",
                "sendmmsg",
                "sendmsg",
                "sendto",
                "setfsgid",
                "setfsgid32",
                "setfsuid",
                "setfsuid32",
                "setgid",
                "setgid32",
                "setgroups",
                "setgroups32",
                "setitimer",
                "setpgid",
                "setpriority",
                "setregid",
                "setregid32",
                "setresgid",
                "setresgid32",
                "setresuid",
                "setresuid32",
                "setreuid",
                "setreuid32",
                "setrlimit",
                "set_robust_list",
                "setsid",
                "setsockopt",
                "set_thread_area",
                "set_tid_address",
                "setuid",
                "setuid32",
                "setxattr",
                "shmat",
                "shmctl",
                "shmdt",
                "shmget",
                "shutdown",
                "sigaltstack",
                "signalfd",
                "signalfd4",
                "sigprocmask",
                "sigreturn",
                "socketcall",
                "socketpair",
                "splice",
                "stat",
                "stat64",
                "statfs",
                "statfs64",
                "statx",
                "symlink",
                "symlinkat",
                "sync",
                "sync_file_range",
                "syncfs",
                "sysinfo",
                "tee",
                "tgkill",
                "time",
                "timer_create",
                "timer_delete",
                "timer_getoverrun",
                "timer_gettime",
                "timer_gettime64",
                "timer_settime",
                "timer_settime64",
                "timerfd_create",
                "timerfd_gettime",
                "timerfd_gettime64",
                "timerfd_settime",
                "timerfd_settime64",
                "times",
                "tkill",
                "truncate",
                "truncate64",
                "ugetrlimit",
                "umask",
                "uname",
                "unlink",
                "unlinkat",
                "utime",
                "utimensat",
                "utimensat_time64",
                "utimes",
                "vfork",
                "vmsplice",
                "wait4",
                "waitid",
                "waitpid",
                "write",
                "writev"
            ],
            "action": "SCMP_ACT_ALLOW"
        },
        {
            "names": [
                "process_vm_readv",
                "process_vm_writev",
                "ptrace"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "minKernel": "4.8"
            }
        },
        {
            "names": [
                "socket"
            ],
            "action": "SCMP_ACT_ALLOW",
            "args": [
                {
                    "index": 0,
                    "value": 40,
                    "op": "SCMP_CMP_NE"
                }
            ]
        },
        {
            "names": [
                "personality"
            ],
            "action": "SCMP_ACT_ALLOW",
            "args": [
                {
                    "index": 0,
                    "value": 0,
                    "op": "SCMP_CMP_EQ"
                }
            ]
        },
        {
            "names": [
                "personality"
            ],
            "action": "SCMP_ACT_ALLOW",
            "args": [
                {
                    "index": 0,
                    "value": 8,
                    "op": "SCMP_CMP_EQ"
                }
            ]
        },
        {
            "names": [
                "personality"
            ],
            "action": "SCMP_ACT_ALLOW",
            "args": [
                {
                    "index": 0,
                    "value": 131072,
                    "op": "SCMP_CMP_EQ"
                }
            ]
        },
        {
            "names": [
                "personality"
            ],
            "action": "SCMP_ACT_ALLOW",
            "args": [
                {
                    "index": 0,
                    "value": 131080,
                    "op": "SCMP_CMP_EQ"
                }
            ]
        },
        {
            "names": [
                "personality"
            ],
            "action": "SCMP_ACT_ALLOW",
            "args": [
                {
                    "index": 0,
                    "value": 4294967295,
                    "op": "SCMP_CMP_EQ"
                }
            ]
        },
        {
            "names": [
                "sync_file_range2",
                "swapcontext"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "arches": [
                    "ppc64le"
                ]
            }
        },
        {
            "names": [
                "arm_fadvise64_64",
                "arm_sync_file_range",
                "sync_file_range2",
                "breakpoint",
                "cacheflush",
                "set_tls"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "arches": [
                    "arm",
                    "arm64"
                ]
            }
        },
        {
            "names": [
                "arch_prctl"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "arches": [
                    "amd64",
                    "x32"
                ]
            }
        },
        {
            "names": [
                "modify_ldt"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "arches": [
                    "amd64",
                    "x32",
                    "x86"
                ]
            }
        },
        {
            "names": [
                "s390_pci_mmio_read",
                "s390_pci_mmio_write",
                "s390_runtime_instr"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "arches": [
                    "s390",
                    "s390x"
                ]
            }
        },
        {
            "names": [
                "riscv_flush_icache"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "arches": [
                    "riscv64"
                ]
            }
        },
        {
            "names": [
                "open_by_handle_at"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_DAC_READ_SEARCH"
                ]
            }
        },
        {
            "names": [
                "bpf",
                "clone",
                "clone3",
                "fanotify_init",
                "fsconfig",
                "fsmount",
                "fsopen",
                "fspick",
                "lookup_dcookie",
                "mount",
                "mount_setattr",
                "move_mount",
                "name_to_handle_at",
                "open_tree",
                "perf_event_open",
                "quotactl",
                "quotactl_fd",
                "setdomainname",
                "sethostname",
                "setns",
                "syslog",
                "umount",
                "umount2",
                "unshare"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_ADMIN"
                ]
            }
        },
        {
            "names": [
                "clone"
            ],
            "action": "SCMP_ACT_ALLOW",
            "args": [
                {
                    "index": 0,
                    "value": 2114060288,
                    "op": "SCMP_CMP_MASKED_EQ"
                }
            ],
            "excludes": {
                "caps": [
                    "CAP_SYS_ADMIN"
                ],
                "arches": [
                    "s390",
                    "s390x"
                ]
            }
        },
        {
            "names": [
                "clone"
            ],
            "action": "SCMP_ACT_ALLOW",
            "args": [
                {
                    "index": 1,
                    "value": 2114060288,
                    "op": "SCMP_CMP_MASKED_EQ"
                }
            ],
            "comment": "s390 parameter ordering for clone is different",
            "includes": {
                "arches": [
                    "s390",
                    "s390x"
                ]
            },
            "excludes": {
                "caps": [
                    "CAP_SYS_ADMIN"
                ]
            }
        },
        {
            "names": [
                "clone3"
            ],
            "action": "SCMP_ACT_ERRNO",
            "errnoRet": 38,
            "excludes": {
                "caps": [
                    "CAP_SYS_ADMIN"
                ]
            }
        },
        {
            "names": [
                "reboot"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_BOOT"
                ]
            }
        },
        {
            "names": [
                "chroot"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_CHROOT"
                ]
            }
        },
        {
            "names": [
                "delete_module",
                "init_module",
                "finit_module"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_MODULE"
                ]
            }
        },
        {
            "names": [
                "acct"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_PACCT"
                ]
            }
        },
        {
            "names": [
                "kcmp",
                "pidfd_getfd",
                "process_madvise",
                "process_vm_readv",
                "process_vm_writev",
                "ptrace"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_PTRACE"
                ]
            }
        },
        {
            "names": [
                "iopl",
                "ioperm"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_RAWIO"
                ]
            }
        },
        {
            "names": [
                "settimeofday",
                "stime",
                "clock_settime",
                "clock_settime64"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_TIME"
                ]
            }
        },
        {
            "names": [
                "vhangup"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_TTY_CONFIG"
                ]
            }
        },
        {
            "names": [
                "get_mempolicy",
                "mbind",
                "set_mempolicy"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYS_NICE"
                ]
            }
        },
        {
            "names": [
                "syslog"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_SYSLOG"
                ]
            }
        },
        {
            "names": [
                "bpf"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_BPF"
                ]
            }
        },
        {
            "names": [
                "perf_event_open"
            ],
            "action": "SCMP_ACT_ALLOW",
            "includes": {
                "caps": [
                    "CAP_PERFMON"
                ]
            }
        }
    ]
}