0
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?

Spring Bootを「動かす」単位を分解する ― 実行可能JARからコンテナまで

0
Last updated at Posted at 2026-09-13

Spring Bootを「動かす」単位を分解する ― 実行可能JARからコンテナまで

手元では動くJARを、そのままコンテナへコピーしたらイメージの再構築が毎回重い。原因を調べるには、JARとコンテナを一つの黒い箱として扱わず、何がどの頻度で変わるかへ分けて見る必要があります。

この回では、実行可能JAR、外部設定、コンテナレイヤー、ヘルス確認を「運ぶ単位」として整理します。Kubernetesの機能一覧やクラウドサービス比較は扱いません。

実行可能JARは何をまとめているか

./mvnw.cmd clean package
jar tf target/order-sample-0.0.1-SNAPSHOT.jar

Spring BootのJARでは、アプリのクラスがBOOT-INF/classes/、依存ライブラリがBOOT-INF/lib/に分かれます。MANIFEST.MFにはSpring Bootの起動ローダーと、実際のアプリケーション開始クラスに関する情報が入ります。

依存ライブラリとアプリケーションを変更頻度でレイヤー分割する

java -jar target/order-sample-0.0.1-SNAPSHOT.jar

この形なら、アプリケーションサーバーへWARを配置する手順を用意せず、JAR自身を実行単位として扱えます。

設定をJARへ焼き込みすぎない

DB接続先やログレベルなど、環境で変わる値は外から渡します。

$env:SPRING_PROFILES_ACTIVE='production'
$env:SPRING_DATASOURCE_URL='jdbc:postgresql://db.example/order'
java -jar target/order-sample-0.0.1-SNAPSHOT.jar

パスワードを記事やDockerfileへ直書きしません。本番環境ではSecret管理の仕組みを使います。

レイヤーへ分ける理由

アプリケーションコードは頻繁に変わりますが、Spring Frameworkなどの依存ライブラリは毎回変わるとは限りません。変化の頻度が違うものを同じコンテナレイヤーへ詰めると、小さなコード変更でも大きな依存層を作り直します。

Spring Bootのレイヤー構成では、概ね次の単位へ分けられます。

レイヤー 主な内容 変化の傾向
dependencies リリース版の依存ライブラリ 比較的低頻度
spring-boot-loader Spring Bootの起動ローダー Boot更新時
snapshot-dependencies SNAPSHOT依存(本サンプルは0件のため図では0 MB) 開発中は変わりやすい
application 自作クラスとリソース 通常の開発で高頻度

依存レイヤーを再利用できれば、アプリケーションコードだけを変更したときの転送量と再構築範囲を抑えられます。これは実行性能の話ではなく、主にビルドと配布の効率の話です。

BuildpacksでOCIイメージを作る

Spring Boot Maven Pluginを使う場合は、Dockerfileを自分で書かずにOCIイメージを作れます。

./mvnw.cmd spring-boot:build-image `
  -Dspring-boot.build-image.imageName=example/order-sample:0.1.0
docker run --rm -p 8080:8080 `
  -e SPRING_PROFILES_ACTIVE=container `
  example/order-sample:0.1.0

containerプロファイルは例示であり、本サンプルに固有設定は含みません。

Buildpacksは便利ですが、ベースイメージ、JVM、SBOM、利用者、証明書などの運用条件を確認せずに採用するものではありません。組織のコンテナ基準がある場合は、それに合わせてDockerfile方式を選ぶこともあります。

Dockerfileで分ける場合の考え方

次はSpring Boot 3.5のtools jarmodeを使う最小例です。抽出後は各レイヤーを配置し、生成されたapplication.jarを実行します。

FROM eclipse-temurin:17-jre AS builder
WORKDIR /workspace
COPY target/order-sample-0.0.1-SNAPSHOT.jar application.jar
RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted

FROM eclipse-temurin:17-jre
WORKDIR /application
COPY --from=builder /workspace/extracted/dependencies/ ./
COPY --from=builder /workspace/extracted/spring-boot-loader/ ./
COPY --from=builder /workspace/extracted/snapshot-dependencies/ ./
COPY --from=builder /workspace/extracted/application/ ./
ENTRYPOINT ["java", "-jar", "application.jar"]

Spring Boot 3.5.16でextract --layersを実行し、dependenciesspring-boot-loadersnapshot-dependenciesapplicationへ分かれることと、抽出後のapplication.jarを実行単位にすることを確認しました。今回の小さなサンプルでは、依存層が約58MB、application JARが約21KBでした。これは構成によって変わる測定例であり、一般的なサイズ保証ではありません。

起動したことと、使えることを分ける

プロセスが存在しても、DBへ接続できず注文APIが使えない場合があります。ActuatorのHealth情報を、コンテナのヘルスチェックやオーケストレーターのProbeへつなげます。

management.endpoint.health.probes.enabled=true
management.endpoints.web.exposure.include=health
curl.exe http://localhost:8080/actuator/health/liveness
curl.exe http://localhost:8080/actuator/health/readiness
  • liveness:プロセスを再起動すべき状態か
  • readiness:現在リクエストを受け付けてよいか

この二つを同じ意味として扱うと、外部サービスの一時障害でコンテナを再起動し続ける設計になり得ます。

livenessとreadinessは異なる状態遷移を表す

上記設定(probes.enabled=true)でのSpring Boot 3.5.16のローカル起動では、/actuator/health/actuator/health/liveness/actuator/health/readinessがいずれもUPになることを確認しました。これはH2を使う単純なサンプルの結果です。本番では、どの依存先をreadinessへ含めるかを設計します。

デプロイ前の確認項目

  • 使用したSpring Boot、Java、ベースイメージの版を記録したか
  • JARとコンテナの両方で同じテストを通したか
  • 設定とSecretをイメージから分離したか
  • ヘルスチェックの意味と公開範囲を決めたか
  • 依存ライブラリとベースイメージの脆弱性対応手順があるか

実務ではこうなる

コンテナ化しても、Javaの保守が消えるわけではありません。Spring Boot、JDK、OSパッケージ、ベースイメージを一組の配布物として追跡します。イメージのタグをlatestだけにせず、再現できる版とダイジェストを記録します。

BuildpacksとDockerfileのどちらを選んでも、非root実行、読み取り専用ファイルシステム、証明書、タイムゾーン、JVMメモリ、SBOM、脆弱性スキャンは別途確認します。コンテナのメモリ上限をJVMが認識していても、ヒープ以外の領域を含めた余白が必要です。

この作業環境ではDocker Engineを使ったイメージ実行までは行っていません。JARの起動、layer抽出、Health応答は実測済み、BuildpacksとDockerfileのコマンドはSpring Boot 3.5公式資料に基づくものとして区別しています。公開前・採用前には、実際のCIと配備基盤でイメージビルド、非root実行、Probe、再ビルド時のキャッシュを確認してください。

公式リファレンス

参考文献・参照資料

  • Somnath Musib, Spring Boot in Practice, Manning, ISBN 9781617298813:第9章のJAR、レイヤー、コンテナを参照。
  • Mark Heckler, Spring Boot:立ち上げて実行する、ISBN 9798341626911(AI翻訳版):実行可能JARの説明を補助参照。

書籍のコマンドやアプリ名は転載せず、架空の注文受付アプリへ置き換えています。Spring Boot 3.5で変わった抽出手順は、公式資料と3.5.16の実行結果で確認しました。

このシリーズでは、起動、DI、設定、HTTP、JPA、トランザクション、自動設定、テスト、配布を一つの注文受付サンプルでつなぎました。新しいアノテーションに出会ったときも、誰が起動時に読み、どのBeanやProxyを作り、どの境界へ処理を差し込むかへ戻ると、暗記から設計へ進めます。

シリーズ内リンク

0
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
0
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?