開発時のサービス
開発時サービスは、開発中にアプリケーションを実行するために必要な外部依存関係を提供します。これらは開発中にのみ使用されることになっており、アプリケーションがデプロイされると無効になります。
Spring Boot は、Docker Compose と Testcontainers という 2 つの開発時間サービスをサポートしています。次のセクションでは、それらについて詳しく説明します。
Docker Compose サポート
Docker Compose は、アプリケーションが必要とするサービスの複数のコンテナーを定義および管理するために使用できる一般的なテクノロジです。compose.yml
ファイルは通常、サービスコンテナーを定義および構成するアプリケーションの隣に作成されます。
Docker Compose の一般的なワークフローは、docker compose up
を実行し、開始されたサービスに接続してアプリケーションを操作し、完了したら docker compose down
を実行します。
spring-boot-docker-compose
モジュールをプロジェクトに含めると、Docker Compose を使用したコンテナーの操作のサポートを提供できます。次の Maven および Gradle のリストに示すように、モジュールの依存関係をビルドに追加します。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
dependencies {
developmentOnly("org.springframework.boot:spring-boot-docker-compose")
}
このモジュールが依存関係として含まれている場合、Spring Boot は次のことを行います。
作業ディレクトリで
compose.yml
やその他の一般的な compose ファイル名を検索します検出された
compose.yml
を使用してdocker compose up
を呼び出しますサポートされているコンテナーごとにサービス接続 Bean を作成する
アプリケーションのシャットダウン時に
docker compose stop
を呼び出します
アプリケーションの起動時に Docker Compose サービスがすでに実行されている場合、Spring Boot はサポートされているコンテナーごとにサービス接続 Bean のみを作成します。再び docker compose up
を呼び出すことはなく、アプリケーションのシャットダウン時に docker compose stop
を呼び出すこともありません。
再パッケージ化されたアーカイブには、デフォルトでは Spring Boot の Docker Compose が含まれていません。このサポートを使用する場合は、これを含める必要があります。Maven プラグインを使用する場合は、excludeDockerCompose プロパティを false に設定します。Gradle プラグインを使用する場合は、タスクのクラスパスを構成して developmentOnly 構成を含めます。 |
前提条件
パス上に docker
および docker compose
(または docker-compose
) CLI アプリケーションが必要です。サポートされる Docker Compose の最小バージョンは 2.2.0 です。
サービス接続
サービス接続は、任意の リモートサービスへの接続です。Spring Boot の自動構成は、サービス接続の詳細を消費し、使用して リモートサービスへの接続を確立できます。その場合、接続の詳細は、接続関連の構成プロパティよりも優先されます。
Spring Boot の Docker Compose サポートを使用する場合、コンテナーによってマップされたポートへのサービス接続が確立されます。
Docker compose は通常、コンテナー内のポートがコンピューター上の一時ポートにマップされるような方法で使用されます。例: Postgres サーバーはポート 5432 を使用してコンテナー内で実行されますが、ローカルではまったく異なるポートにマッピングされます。サービス接続は常に、ローカルにマップされたポートを検出して使用します。 |
サービス接続は、コンテナーのイメージ名を使用して確立されます。現在、次のサービス接続がサポートされています。
接続詳細 | 一致 |
---|---|
| "symptoma/activemq" または "apache/activemq-classic" という名前のコンテナー |
| "apache/activemq-artemis" という名前のコンテナー |
| "cassandra" または "bitnami/cassandra" という名前のコンテナー |
| "elasticsearch" または "bitnami/elasticsearch" という名前のコンテナー |
| "gvenzl/oracle-free"、"gvenzl/oracle-xe"、"mariadb"、"bitnami/mariadb"、"mssql/server"、"mysql"、"bitnami/mysql"、"postgres"、"" という名前のコンテナービットナミ / ポストグレ SQL」 |
| "osixia/openldap" という名前のコンテナー |
| "mongo" または "bitnami/mongodb" という名前のコンテナー |
| "neo4j" または "bitnami/neo4j" という名前のコンテナー |
| "otel/opentelemetry-collector-contrib" という名前のコンテナー |
| "otel/opentelemetry-collector-contrib" という名前のコンテナー |
| "apachepulsar/pulsar" という名前のコンテナー |
| "gvenzl/oracle-free"、"gvenzl/oracle-xe"、"mariadb"、"bitnami/mariadb"、"mssql/server"、"mysql"、"bitnami/mysql"、"postgres"、"" という名前のコンテナービットナミ / ポストグレ SQL」 |
| "rabbitmq" または "bitnami/rabbitmq" という名前のコンテナー |
| "redis" または "bitnami/redis" という名前のコンテナー |
| "openzipkin/zipkin" という名前のコンテナー。 |
カスタム画像
サービスを提供するために、独自のバージョンのイメージを使用する必要がある場合があります。標準イメージと同じように動作する限り、任意のカスタムイメージを使用できます。具体的には、標準イメージがサポートする環境変数はカスタムイメージでも使用する必要があります。
イメージで別の名前が使用されている場合は、Spring Boot がサービス接続を提供できるように、compose.yml
ファイルでラベルを使用できます。org.springframework.boot.service-connection
という名前のラベルを使用してサービス名を指定します。
例:
services:
redis:
image: 'mycompany/mycustomredis:7.0'
ports:
- '6379'
labels:
org.springframework.boot.service-connection: redis
特定のコンテナーをスキップする
compose.yml
で定義されたコンテナーイメージがアプリケーションに接続したくない場合は、ラベルを使用してそれを無視できます。org.springframework.boot.ignore
というラベルが付いたコンテナーは、Spring Boot によって無視されます。
例:
services:
redis:
image: 'redis:7.0'
ports:
- '6379'
labels:
org.springframework.boot.ignore: true
特定の構成ファイルの使用
作成ファイルがアプリケーションと同じディレクトリにない場合、または別の名前が付けられている場合は、application.properties
または application.yaml
で spring.docker.compose.file
を使用して別のファイルを指すことができます。プロパティは、正確なパスまたはアプリケーションに対する相対パスとして定義できます。
例:
プロパティ
YAML
spring.docker.compose.file=../my-compose.yml
spring:
docker:
compose:
file: "../my-compose.yml"
コンテナーの準備が完了するまで待機
Docker Compose によって開始されたコンテナーは、完全に準備が完了するまでに時間がかかる場合があります。準備が整っているかどうかを確認する推奨方法は、compose.yml
ファイルのサービス定義に healthcheck
セクションを追加することです。
healthcheck
構成が compose.yml
ファイルから省略されることは珍しいことではないため、Spring Boot はサービスの準備状況を直接チェックします。デフォルトでは、マップされたポートへの TCP/IP 接続を確立できる場合、コンテナーは準備完了とみなされます。
compose.yml
ファイルに org.springframework.boot.readiness-check.tcp.disable
ラベルを追加することで、コンテナーごとにこれを無効にできます。
例:
services:
redis:
image: 'redis:7.0'
ports:
- '6379'
labels:
org.springframework.boot.readiness-check.tcp.disable: true
application.properties
または application.yaml
ファイルでタイムアウト値を変更することもできます。
プロパティ
YAML
spring.docker.compose.readiness.tcp.connect-timeout=10s
spring.docker.compose.readiness.tcp.read-timeout=5s
spring:
docker:
compose:
readiness:
tcp:
connect-timeout: 10s
read-timeout: 5s
全体のタイムアウトは spring.docker.compose.readiness.timeout
を使用して構成できます。
Docker Compose ライフサイクルの制御
デフォルトでは、Spring Boot はアプリケーションの起動時に docker compose up
を呼び出し、シャットダウン時に docker compose stop
を呼び出します。別のライフサイクル管理を使用したい場合は、spring.docker.compose.lifecycle-management
プロパティを使用できます。
次の値がサポートされています。
none
- Docker Compose を起動または停止しないでくださいstart-only
- アプリケーションの起動時に Docker Compose を起動し、実行したままにします。start-and-stop
- アプリケーションの起動時に Docker Compose を起動し、JVM の終了時に停止します。
さらに、spring.docker.compose.start.command
プロパティを使用して、docker compose up
または docker compose start
のどちらを使用するかを変更できます。spring.docker.compose.stop.command
では、docker compose down
または docker compose stop
を使用するかどうかを設定できます。
次の例は、ライフサイクル管理を構成する方法を示しています。
プロパティ
YAML
spring.docker.compose.lifecycle-management=start-and-stop
spring.docker.compose.start.command=start
spring.docker.compose.stop.command=down
spring.docker.compose.stop.timeout=1m
spring:
docker:
compose:
lifecycle-management: start-and-stop
start:
command: start
stop:
command: down
timeout: 1m
Docker Compose プロファイルのアクティブ化
Docker Compose プロファイルは、特定の環境に合わせて Docker Compose 構成を調整できるという点で Spring プロファイルに似ています。特定の Docker Compose プロファイルをアクティブ化する場合は、application.properties
または application.yaml
ファイルで spring.docker.compose.profiles.active
プロパティを使用できます。
プロパティ
YAML
spring.docker.compose.profiles.active=myprofile
spring:
docker:
compose:
profiles:
active: "myprofile"
テストでの Docker Compose の使用
デフォルトでは、テストの実行時に Spring Boot の Docker Compose サポートは無効になっています。
テストで Docker Compose サポートを有効にするには、spring.docker.compose.skip.in-tests
を false
に設定します。
Gradle を使用する場合は、spring-boot-docker-compose
依存関係の構成を developmentOnly
から testAndDevelopmentOnly
に変更する必要もあります。
dependencies {
testAndDevelopmentOnly("org.springframework.boot:spring-boot-docker-compose")
}
テストコンテナーのサポート
Testcontainers を統合テストに使用するだけでなく、開発時に使用することもできます。次のセクションでは、これについて詳しく説明します。
開発時のテストコンテナーの使用
このアプローチにより、開発者はアプリケーションが依存するサービスのコンテナーを迅速に起動できるため、データベースサーバーなどを手動でプロビジョニングする必要がなくなります。この方法で Testcontainers を使用すると、コンテナー構成が YAML ではなく Java であることを除いて、Docker Compose と同様の機能が提供されます。
開発時に Testcontainer を使用するには、"main" クラスパスではなく "test" クラスパスを使用してアプリケーションを起動する必要があります。これにより、宣言されたすべてのテスト依存関係にアクセスできるようになり、テスト構成を自然に記述できる場所が提供されます。
アプリケーションのテスト起動可能なバージョンを作成するには、src/test
ディレクトリに "Application" クラスを作成する必要があります。例: メインアプリケーションが src/main/java/com/example/MyApplication.java
にある場合は、src/test/java/com/example/TestMyApplication.java
を作成する必要があります
TestMyApplication
クラスは、SpringApplication.from(…)
メソッドを使用して実際のアプリケーションを起動できます。
import org.springframework.boot.SpringApplication;
public class TestMyApplication {
public static void main(String[] args) {
SpringApplication.from(MyApplication::main).run(args);
}
}
アプリケーションと一緒に開始する Container
インスタンスも定義する必要があります。これを行うには、spring-boot-testcontainers
モジュールが test
依存関係として追加されていることを確認する必要があります。それが完了したら、開始するコンテナーの @Bean
メソッドを宣言する @TestConfiguration
クラスを作成できます。
ConnectionDetails
Bean を作成するために、@Bean
メソッドに @ServiceConnection
アノテーションを付けることもできます。サポートされているテクノロジーの詳細については、「サービス接続」セクションを参照してください。
典型的な Testcontainers 構成は次のようになります。
import org.testcontainers.containers.Neo4jContainer;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {
@Bean
@ServiceConnection
public Neo4jContainer<?> neo4jContainer() {
return new Neo4jContainer<>("neo4j:5");
}
}
Container Bean のライフサイクルは、Spring Boot によって自動的に管理されます。コンテナーは自動的に起動および停止されます。 |
spring.testcontainers.beans.startup プロパティを使用して、コンテナーの起動方法を変更できます。デフォルトでは sequential 起動が使用されますが、複数のコンテナーを並行して起動する場合は、parallel を選択することもできます。 |
テスト構成を定義したら、with(…)
メソッドを使用してテストランチャーに接続できます。
import org.springframework.boot.SpringApplication;
public class TestMyApplication {
public static void main(String[] args) {
SpringApplication.from(MyApplication::main).with(MyContainersConfiguration.class).run(args);
}
}
これで、通常の Java main
メソッドアプリケーションと同じように TestMyApplication
を起動して、アプリケーションと実行する必要のあるコンテナーを開始できるようになりました。
Maven ゴール spring-boot:test-run または Gradle タスク bootTestRun を使用して、コマンドラインからこれを行うことができます。 |
開発時に動的プロパティを提供する
開発時に Container
@Bean
メソッドから動的プロパティを提供したい場合は、DynamicPropertyRegistry
を注入することで実行できます。これは、テストで使用できる @DynamicPropertySource
アノテーションと同様の方法で機能します。これにより、コンテナーの起動後に使用可能になるプロパティを追加できます。
一般的な構成は次のようになります。
import org.testcontainers.containers.MongoDBContainer;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.DynamicPropertyRegistry;
@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {
@Bean
public MongoDBContainer mongoDbContainer(DynamicPropertyRegistry properties) {
MongoDBContainer container = new MongoDBContainer("mongo:5.0");
properties.add("spring.data.mongodb.host", container::getHost);
properties.add("spring.data.mongodb.port", container::getFirstMappedPort);
return container;
}
}
可能な限り @ServiceConnection を使用することをお勧めしますが、動的プロパティは、まだ @ServiceConnection をサポートしていないテクノロジにとって有用なフォールバックになる可能性があります。 |
Testcontainer 宣言クラスのインポート
Testcontainers を使用する場合の一般的なパターンは、Container
インスタンスを静的フィールドとして宣言することです。多くの場合、これらのフィールドはテストクラスで直接定義されます。親クラスまたはテストが実装するインターフェース上で宣言することもできます。
例: 次の MyContainers
インターフェースは、mongo
コンテナーと neo4j
コンテナーを宣言します。
import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
public interface MyContainers {
@Container
@ServiceConnection
MongoDBContainer mongoContainer = new MongoDBContainer("mongo:5.0");
@Container
@ServiceConnection
Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:5");
}
すでにこの方法でコンテナーを定義している場合、またはこのスタイルを好む場合は、コンテナーを @Bean
メソッドとして定義するのではなく、これらの宣言クラスをインポートできます。これを行うには、テスト構成クラスに @ImportTestcontainers
アノテーションを追加します。
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.context.ImportTestcontainers;
@TestConfiguration(proxyBeanMethods = false)
@ImportTestcontainers(MyContainers.class)
public class MyContainersConfiguration {
}
サービス接続機能を使用するつもりはなく、代わりに @DynamicPropertySource を使用したい場合は、Container フィールドから @ServiceConnection アノテーションを削除します。@DynamicPropertySource アノテーション付きメソッドを宣言クラスに追加することもできます。 |
開発時にテストコンテナーで DevTools を使用する
devtools を使用する場合、Bean および Bean メソッドに @RestartScope
のアノテーションを付けることができます。このような Bean は、devtools がアプリケーションを再起動するときに再作成されません。これは、アプリケーションの再起動にもかかわらず状態が維持されるため、Testcontainer Container
Bean の場合に特に便利です。
import org.testcontainers.containers.MongoDBContainer;
import org.springframework.boot.devtools.restart.RestartScope;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {
@Bean
@RestartScope
@ServiceConnection
public MongoDBContainer mongoDbContainer() {
return new MongoDBContainer("mongo:5.0");
}
}
Gradle を使用していてこの機能を使用したい場合は、spring-boot-devtools 依存関係の構成を developmentOnly から testAndDevelopmentOnly に変更する必要があります。デフォルトのスコープ developmentOnly では、devtools がアクティブではないため、bootTestRun タスクはコード内の変更を取得しません。 |