SonarQubeをDockerContainerにしてみた話

# はじめに
[WebサービスのJava11対応をしてみた話](https://qiita.com/awakuwaku/items/22ba019184b1a3ab3b75) のコード解析ツール `SonarQube` に関する部分です。


# 経緯
Javaのコード解析ツールはcheckstyle、FindBugs、SpotBugs、fb-contrib等多々ありますが、私のプロジェクトでは、SonarQubeを利用していました。

Java8からJava11へのアップグレード対応を進めていた中で、コードがある程度完成したところでSonarQubeを実行したところまさかの以下のエラー・・・

```java
java.lang.IllegalArgumentException: Unsupported class file major version 55
```

SonarQube(厳密にはSonarJavaPlugin)もJava11対応へのアップグレードが必要なことが判明した瞬間でした。


# SonarQubeアップグレードの課題
SonarQubeアップグレードにあたり、調査したところ環境面、運用面の課題がいくつかあり、今回の対応の中で合わせて対応した方がよいと判断しました。

課題1. SonarQubeおよびＳｏｎａｒＱｕｂｅ用のDBが個別サーバで管理されている上、ＯＳやソフトウェアのパッチ適用が運用開始当初(少なくとも1年以上)から実施されていない
課題2. Ｊａｖａ11対応のSonarJavaはＳｏｎａｒＱｕｂｅ7.x以上でないと上手く動かない可能性がある(運用しているSonarQubeが6.xのためメジャーバージョンアップが必要）
課題3. ネットワーク等の制限から開発者が開発端末上ではSonarQubeが利用できずプルリクエストやマージ直前までコード解析が行えず作業の手戻りが多発していた


# SonarQubeアップグレード課題解決策
課題1. 個別サーバで管理しているのが問題 -> DockerContainer化して他用途で運用されている開発用のサーバに集約しよう
課題2. 古いSonarQubeを利用しているのが問題 -> SonarQubeのDockerContainerイメージでは新バージョンが公開されているので利用しよう
課題3. 開発端末上で実行できるSonarQubeがないことが問題 -> DockerContainer化して配布しよう

DockerContainerにすることで全ての課題が解決するのではないかと考え、SonarQubeのDockerContainer化を開始することにしました。


# SonarQubeのDokcerContainer化
[DockerHubで公開されているSonarQube](https://hub.docker.com/_/sonarqube/)をお借りして、 `docker-compose.yml` を以下のように作成しました。

```yaml
version: '2'
services:
  mysql-sonarqube:
    container_name: mysql-sonarqube
    image: mysql:5.7.24
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    volumes:
      - "./data/mysql/init:/docker-entrypoint-initdb.d"
      - "./data/mysql/db:/var/lib/mysql"
    ports:
      - "3306:3306"
    networks:
      - sonarqube-server-network
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=sonar
      - MYSQL_USER=sonar
      - MYSQL_PASSWORD=sonar

  # SonarQube Server
  sonarqube-server:
    container_name: sonarqube-server
    image: sonarqube:7.4-community
    command: -Dsonar.web.context=/sonarqube
    links:
      - mysql-sonarqube:mysql
    volumes:
      - ./data/sonarqube/extensions/plugin:/opt/sonarqube/extensions/plugins
    ports:
      - "9000:9000"
      - "9092:9092"
    networks:
      - sonarqube-server-network
    environment:
      - SONARQUBE_JDBC_USERNAME=sonar
      - SONARQUBE_JDBC_PASSWORD=sonar
      - "SONARQUBE_JDBC_URL=jdbc:mysql://mysql:3306/sonar?useUnicode=true&characterEncoding=utf8&useSSL=false"

networks:
  sonarqube-server-network:
```


# 実際の運用について
- 実行環境
開発用のサーバとしてCI/CD用に高スペックなものが存在したので、該当サーバ上でDockerContainerを起動して運用。起動・終了等はジョブ化して運用手離れをしています。

- DockerContainerイメージの配布
`docker-compose.yml` をgitリポジトリ管理し、変更起因で実行環境で起動するような配布をしています。また開発者のgitリポジトリを参照することで開発端末上で自由にSonarQubeを利用できるようになりました。

- SonarQubeの解析ルールの展開
SonarQubeの解析ルールのカスタマイズ等は、SonarQube上のDBに格納されているため、DBのデータをエクスポートし、以下部分で起動時にロードすることで皆同じ解析ルールで実行できるようになりました。

```yaml
volumes:
  - "./data/mysql/init:/docker-entrypoint-initdb.d"
```

- SonarQubeの時系列解析
DBがDockerContainerになったのことで過去データを利用した時系列解析のデータが揮発性になりましたが、私のいるプロジェクトでは最新のものを対象に確認しているので実害はありませんでした。
必要になったところで、以下のDBのボリューム部分を永続化できる場所に移動したら良いかなと考えています。

```yaml
volumes:
  - "./data/mysql/db:/var/lib/mysql"
```


# 感想
別の対応から始まったSonarQubeのDockerContainer化ですが、周囲からは管理対象サーバ減少や開発端末上でのコード解析ができる点から概ね好評でした。
また、DockerContainer化で資源管理もリポジトリ化でき見えるかもできたのが良かったと思っています。

本記事の対応は以下のgithubリポジトリに公開していますので興味ありましたら参考にしてください。
https://github.com/awakuwaku/sonar-qube-docker


# 参考
- https://hub.docker.com/_/sonarqube/
- https://hub.docker.com/_/mysql