Java - Spring Batchのjarをビルドした際にDockerイメージもビルドする(Gradle)
Spring Batchで作成した.jarをDockerコンテナとして実行したい事情があった。
Gradleのビルド時にイメージビルドまでまとめてできないかと調べが、情報が少なそうだったので書く。
環境
- JDK: OpenJDK Runtime Environment Temurin-17.0.6+10 (build 17.0.6+10)
- Spring Boot: 2.7.10
- Spring Batch: 4.3.8
- Gradle: 7.6.1
- Docker: 23.0.1, build a5ee5b1dfc
やり方
build.gradleに、ビルド結果の.jarを含めてDockerイメージを作成するタスク定義を追加する。
以下3ファイルをコピペすれば動くはず。
./build.gradle
plugins { id 'java' id 'org.springframework.boot' version '2.7.10-SNAPSHOT' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } maven { url 'https://repo.spring.io/snapshot' } } dependencies { implementation 'org.springframework.boot:spring-boot-starter-batch' runtimeOnly 'com.h2database:h2' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.batch:spring-batch-test' } + // buildタスクの実行後、生成された.jarをDockerイメージビルド用にコピーする。 + // ./build/libs配下に置いたままイメージビルドするとビルドコンテキストが + // 大きくなってしまったりignoreを書くのが面倒だったりなので。 + build.doLast { + copy { + from "./build/libs/demo-0.0.1-SNAPSHOT.jar" + into "./docker/" + rename "demo-0.0.1-SNAPSHOT.jar", "demo.jar" + } + // jarビルド時にDockerイメージのビルドも一緒にやってしまった方が楽な場合もあるかもしれない。 + // exec { + // executable 'sh' + // args '-c', 'docker build -t sample_img -f ./docker/Dockerfile ./docker/' + // } + } + clean.doFirst { + delete './docker/demo.jar' + } + // Dockerイメージビルドタスク + task docker(type: Exec) { + executable 'sh' + args '-c', 'docker build -t sample_img -f ./docker/Dockerfile ./docker/' + } + docker.dependsOn build tasks.named('test') { useJUnitPlatform() }
package com.example.demo; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.repeat.RepeatStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import lombok.extern.slf4j.Slf4j; /** * 実行時の引数「nanika」の内容をログ出力するJob. * nanikaが指定されない場合は「デフォルト値です!」をログ出力する. */ @Configuration @EnableBatchProcessing @Slf4j public class SampleJobConfig { @Autowired public JobBuilderFactory jobFactory; @Autowired public StepBuilderFactory stepFactory; @Value("${nanika:デフォルト値です!}") private String nanika; @Bean public Job sampleJob(Step sampleStep1) { return jobFactory .get("sampleJob") .incrementer(new RunIdIncrementer()) .start(sampleStep1) .build(); } @Bean public Step sampleStep1() { return stepFactory .get("sampleStep1") .tasklet((contrib, context) -> { log.warn(nanika); return RepeatStatus.FINISHED; }) .build(); } }
./docker/Dockerfile
FROM eclipse-temurin:17.0.4.1_1-jre-jammy RUN addgroup --system spring \ && adduser --system spring \ && usermod -aG spring spring USER spring:spring COPY ./demo.jar demo.jar ENTRYPOINT ["java", "-jar", "/demo.jar"]
jarとDockerイメージのビルド
Gradleでdockerタスクを実行すれば、jarのビルドからDockerイメージの作成までやってくれる。
./gradlew docker
Dockerコンテナ実行
実行すると標準出力の警告ログに「なんらかのパラメータ」が表示されるはず。
docker run --rm sample_img --nanika=なんらかのパラメータ