daisuzz.log

Spring Boot 3.1でサポートされたDocker Composeとの統合機能を試してみる

Spring Boot 3.1でDocker Composeとの統合機能がリリースされたので試してみる。

何ができるようになったのか

Spring Boot 3.1からDocker Composeとの統合機能がリリースされ、Spring Boot アプリケーションを起動/停止すると、そのタイミングに合わせて自動的にdocker-compose updocker-compose stopが実行され、Dockerコンテナが起動/停止するようになった。

公式ドキュメントを読むと、以下のような流れで処理が実行される。

  1. Spring Bootアプリケーションが起動すると、自動的にカレントディレクトリのDocker Compose構成ファイルを検索
  2. 見つけたDocker Compose構成ファイルを使って、docker compose upでサービスを起動
  3. サポートされている各コンテナに対してService ConnectionのBeanを作成
  4. アプリケーションが停止するとdocker compose stopでコンテナをシャットダウンする

1で検索対象となるDocker Compose構成ファイルは以下。

  • compose.yaml
  • compose.yml
  • docker-compose.yaml
  • docker-compose.yml

上記以外のファイルを読み込ませたい場合は、spring.docker.compose.fileというプロパティでファイル名を設定する。 相対パス, 絶対パスどちらでもOK。

spring:
  docker:
    compose:
      file: "./my-docker-compose.yml"

3のService Connectionとは、Spring Boot 3.1から導入された、接続に関する情報を表す概念。 従来はapplicaiton.propertiesapplication.ymlなどの設定ファイルで指定した情報を元にXXXXPropertiesというクラスで接続情報が表現されていたが、設定ファイル以外からでも接続情報を指定しやすくするために導入された。

Docker Composeとの統合機能では、docker-compose.ymlなどのDocker Compose構成ファイルからコンテナイメージの名前を読み取り、名前に対応するサービスへの接続情報をService ConnectionのBean(ConnectionDetailsと呼ぶ)で表現している。 MySQLやPostgresなどのRDBや、Redis, Elasticsearch, RabbitMQ, OpenTelemetry Collectorなどさまざまなものをサポートしている。 詳細は公式ドキュメントに一覧が記載されている。

試してみる

以下の環境で実際に試してみる。

Docker ComposeとSpring Bootの統合を行う場合、dockerdocker-composeCLIがインストールされていることと、docker-composeのバージョンは2.2.0以上である必要があるので、それも事前に用意しておく。

実際のコードはこちら

github.com

Docker Composeとの統合はspring-boot-docker-composeというモジュールで提供されているので、適当なSpring Bootのプロジェクトを作成して、プロジェクトの依存関係にこのモジュールを追加する。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-docker-compose</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

プロジェクトルート直下に以下のdocker-compose.ymlを用意する。

version: "3.9"
services:
  postgres:
    image: "postgres"
    ports:
      - "5432"
    environment:
      POSTGRES_PASSWORD: test
  redis:
    image: "redis"
    ports:
      - "6379"
  elasticsearch:
    image: "elasticsearch:8.12.2"
    ports:
      - "9200"

この状態でアプリケーションを起動すると、自動的にdocker-compose upが実行され、postgresとredisとelasticsearchの3つのコンテナが立ち上がる。 実際にログを確認するとSpring Bootがdockerコンテナを立ち上げているのが確認できる。

2024-02-27T21:12:40.146+09:00  INFO 6975 --- [           main] .s.b.d.c.l.DockerComposeLifecycleManager : Using Docker Compose file '/Users/daisuzz/repository/daisuzz/sample-spring-boot-3-2/docker-compose.yml'
2024-02-27T21:12:41.720+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-redis-1  Created
2024-02-27T21:12:41.720+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-elasticsearch-1  Created
2024-02-27T21:12:41.720+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-postgres-1  Created
2024-02-27T21:12:41.732+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-elasticsearch-1  Starting
2024-02-27T21:12:41.732+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-redis-1  Starting
2024-02-27T21:12:41.732+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-postgres-1  Starting
2024-02-27T21:12:42.807+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-elasticsearch-1  Started
2024-02-27T21:12:42.815+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-postgres-1  Started
2024-02-27T21:12:42.819+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-redis-1  Started
2024-02-27T21:12:42.820+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-postgres-1  Waiting
2024-02-27T21:12:42.820+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-redis-1  Waiting
2024-02-27T21:12:42.820+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-elasticsearch-1  Waiting
2024-02-27T21:12:43.330+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-elasticsearch-1  Healthy
2024-02-27T21:12:43.330+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-postgres-1  Healthy
2024-02-27T21:12:43.330+09:00  INFO 6975 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli   :  Container sample-spring-boot-3-2-redis-1  Healthy

アプリケーション起動中にdocker psを叩いてみてもdockerコンテナが起動していることがわかる。

$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED       STATUS         PORTS                               NAMES
7e7635d155a4   postgres               "docker-entrypoint.s…"   5 hours ago   Up 2 minutes   0.0.0.0:54923->5432/tcp             sample-spring-boot-3-2-postgres-1
4f1effcaa6a7   elasticsearch:8.12.2   "/bin/tini -- /usr/l…"   5 hours ago   Up 2 minutes   9300/tcp, 0.0.0.0:54922->9200/tcp   sample-spring-boot-3-2-elasticsearch-1
11f4480fd403   redis                  "docker-entrypoint.s…"   5 hours ago   Up 2 minutes   0.0.0.0:54924->6379/tcp             sample-spring-boot-3-2-redis-1

アプリケーションを終了してdocker psを叩くと、dockerコンテナが終了していることがわかる。

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

便利な設定

spring.docker.compose.enabledというプロパティでDocker Composeとの統合機能の有効化を制御できる。 例えばローカル環境でのみDocker Composeとの統合機能を有効化したい場合は、ローカル用の設定ファイルに以下を設定する。

spring:
  docker:
    compose:
      enabled: false

また、spring.docker.compose.profiles.activeというプロパティを使うことで、Docker Composeのprofilesを使って、Springが起動するコンテナを指定できる。

例えば、以下のdocker-compose.ymlを用意した上で、

version: "3.9"
services:
  postgres:
    image: "postgres"
    ports:
      - "5432"
    environment:
      POSTGRES_PASSWORD: test
    profiles:
      - "spring"
  redis:
    image: "redis"
    ports:
      - "6379"
    profiles:
      - "no-spring"

以下のようにSpring Bootの設定ファイルを指定すると、springというプロファイルが指定された、postgresのコンテナのみSpring Bootが起動するようになる。

spring: 
  docker:
    compose:
      profiles:
        active: spring

また、デフォルトではテスト時にはDocker Composeとの統合機能は無効化されているので、テストで使いたい場合はspring.docker.compose.skip.in-testsfalseに設定すればOK。

spring:
  docker:
    compose:
      skip:
        in-tests: false

他にも、Spring Bootアプリケーションの起動/終了時に実行するコマンドを設定できるプロパティや、独自のコンテナイメージをSpring Bootに起動/終了させる方法や、コンテナの立ち上げが完了したかどうかを確認する処理に関するプロパティもある。

(参考リンク)

参考