2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SonarQubeをDocker+systemdで立ち上げようとしたら「無限再起動ループ」にはまった話

Posted at

はじめに

プロジェクトのソースコード解析を自動化するため、OCI上に SonarQube を Docker で構築し、systemd で管理しようとしました。
しかし、いざサービスを起動してみると、コンテナが数秒おきに再作成され続ける「無限ループ」が発生。ログすら出ない沈黙の停止に悩まされた、落とし穴とその解決策を共有します。

また、本記事では実際に使用した環境構築用の設定や、Mavenを用いた解析の実行方法についても触れます。

実行環境

  • OS: Ubuntu 24.04.3 LTS
  • Memory: 16 GB
  • Arch: x86_64
  • Docker Compose: v2.39.2

1. SonarQubeの環境構築

まずはベースとなる環境を構築します。今回は、公式の docker-sonarqube をベースに、PostgreSQLをデータベースとして使用する構成を採用しました。

docker-compose.yml

services:
  sonarqube:
    image: sonarqube:community
    hostname: sonarqube
    container_name: sonarqube
    read_only: true
    depends_on:
      db:
        condition: service_healthy
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
      - sonarqube_temp:/opt/sonarqube/temp
    ports:
      - "9000:9000"
    networks:
      - ${NETWORK_TYPE:-ipv4}
  db:
    image: postgres:17
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]
      interval: 10s
      timeout: 5s
      retries: 5
    hostname: postgresql
    container_name: postgresql
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar
      POSTGRES_DB: sonar
    volumes:
      - postgresql:/var/lib/postgresql
    networks:
      - ${NETWORK_TYPE:-ipv4}

volumes:
  sonarqube_data:
  sonarqube_temp:
  sonarqube_extensions:
  sonarqube_logs:
  postgresql:

networks:
  ipv4:
    driver: bridge
    enable_ipv6: false
  dual:
    driver: bridge
    enable_ipv6: true
    ipam:
      config:
        - subnet: "192.168.2.0/24"
          gateway: "192.168.2.1"
        - subnet: "2001:db8:2::/64"
          gateway: "2001:db8:2::1"

Mavenを用いた解析の実行

環境が整えば、Mavenプロジェクトから以下のコマンドを叩くだけで、簡単に静的解析結果をSonarQubeへ送信できます。

mvn sonar:sonar \
  -Dsonar.projectKey=my-project \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=your-sonarqube-token

これにより、コードの複雑度や潜在的なバグがダッシュボード上で可視化されます。


2. systemd の親切心が招いた「無限再起動ループ」

systemd でサービス化し、Restart=always を設定したところ、コンテナが数秒おきに壊されては作られる地獄のループに突入しました。

問題の設定:

[Service]
ExecStart=/usr/bin/docker compose up -d
Restart=always

なぜループしたのか?:

  1. systemd が docker compose up -d を実行する。
  2. -d(バックグラウンド実行)なので、コンテナを起動した直後にコマンド自体は「正常終了」して終了する。
  3. systemd は「おっと、プログラムが終了したぞ! でも Restart=always だから、すぐにもう一度動かさなきゃ!」と判断。
  4. すぐに再び ExecStart が走る。
  5. docker compose が既存のコンテナを「再作成(Recreate)」して起動し直す。
  6. 以下、無限ループへ。

解決策:
systemd に「コマンドを叩いたら仕事は終わりだよ」と教え、終了後も「起動中」という状態だけを維持させる Type=oneshot 設定に変更します。

修正後の設定(/etc/systemd/system/sonarqube-docker.service):

[Service]
Type=oneshot            # 一回叩いて終わり
RemainAfterExit=yes     # 終了後も「起動中」とみなす
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
Restart=no              # systemdによる勝手な再起動を禁止


💡 コラム:systemdでDockerを管理する「2つの流派」

「そもそも -d を使うのは一般的なのか?」という疑問への回答として、よく使われる2つのパターンを比較します。

管理方法 設定タイプ メリット デメリット
A. フォアグラウンド (-dなし) Type=simple systemdがプロセスを直接監視。ログも journalctl で一元管理。 docker stop 等の外部操作を「異常終了」と誤認しやすい。
B. デタッチモード (-dあり) Type=oneshot 普段の docker compose コマンドと同じ感覚で扱える。 中のコンテナが死んでいても、systemd上は active と表示され続ける。

今回は、運用に慣れている Docker 側での操作感を優先し、Bのデタッチモードを採用しました。systemdを「OS起動時にコンテナを立ち上げるトリガー」として割り切る構成です。


4. まとめ

systemdをよくわからないまま使っていて思わぬ動作をしたので記事にしました。
同じことに悩む誰かの助けになれば幸いです。


おわりに

次回は、この SonarQube 環境をフル活用し、Jenkins Pipelineで400以上のプロジェクトを環境再起動に強い構成で解析した方法について書きたいと思います。


2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?