Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Java × distroless で 軽量なコンテナイメージを / Java on Dist...
Search
Daisuke Garaike
May 29, 2026
Programming
650
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
https://jjugccc2026s.sessionize.com/session/1172902
Daisuke Garaike
May 29, 2026
More Decks by Daisuke Garaike
See All by Daisuke Garaike
S3 を使うアプリケーションをローカル完結で動かすことに全力を注いでみた / Running S3 Apps Offline
contour_gara
0
420
立川で超かぐや姫!について話したい / Talking Cosmic Princess Kaguya! in Tachikawa
contour_gara
1
410
AR グラス + ミニ PC で実現する新しいモバイル環境
contour_gara
0
370
TDD 実践ミニトーク
contour_gara
1
430
Spring Boot と AWS S3 を使ったアプリケーションのテスト
contour_gara
0
150
ノート PC に Linux 入れてみたけど結構良かった
contour_gara
0
3.6k
JUnit5 から Kotest へ
contour_gara
0
220
社外での学びを社内に還元したい
contour_gara
1
580
2 週間で Twitter Bot を作ってみた
contour_gara
0
1.3k
Other Decks in Programming
See All in Programming
OpenSpecのproposalにbrainstormingを持たせてみた
tigertora7571
1
210
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
460
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
370
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
450
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
490
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
470
夏だ!祭りだ!祭りとはドメインモデリングでは?
ryugen04
0
210
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
230
数百円から始めるRuby電子工作
tarosay
0
140
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
540
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
380
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.8k
Featured
See All Featured
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
790
BBQ
matthewcrist
89
10k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
270
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
210
Balancing Empowerment & Direction
lara
6
1.2k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
The Language of Interfaces
destraynor
162
27k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
sira's awesome portfolio website redesign presentation
elsirapls
0
320
Transcript
Java × distroless で 軽量なコンテナイメージを 2026-05-30 JJUG CCC 2026 Spring
Daisuke Garaike
プロポーザルの変更点 • Java のバージョンを変更 ◦ 21 -> 25 2
Daisuke Garaike • Product Engineer ◦ ハンディ株式会社 ◦ Backend ▪
Kotlin, Java • サーバーサイド Kotlin, アジャイル, 自動テスト, プロダクト開発 3
アジェンダ 1. Distroless を使う モチベーション 2. Java アプリを Distroless で
動かす 3. コンテナイメージのサイズと 起動速度の比較 4. Java アプリを Distroless で 動かす際にやってほしいこと 4
Distroless を使うモチベーション 5
なぜコンテナアプリケーション • The Twelve-Factor App ◦ アプリを環境から切り離す ◦ アプリを入れ替え可能に •
ローカルでもクラウドでも 同じものが動く 6
JVM のイメージは重い • docker イメージのサイズ ◦ amazoncorretto: 132.64 MB ◦
eclipse-temurin: 143.42 MB ◦ 参考: ▪ debian: 47.03 MB • これらにアプリケーションが載る • 環境構築時に待たされる • 新規開発時に待たされる • Write Once, Run Anywhere と被っているから? 7
軽量イメージを使って問題解決 • debian-slim: 28.4 MB • Alpine Linux: 3.69 MB
• Distroless: 10.99 MB ◦ Google 管理 ◦ シェルがないため攻撃に強い ◦ Java で Distroless を使っている話を あまり聞かないので今回のテーマに 8
Java アプリを Distroless で動かす 9
サンプルアプリについて • Kotlin, Gradle, Java25, Spring Boot 4.0.6 • ルートエンドポイントに
GET すると "Hello World!" が返る 10
corretto # syntax=docker/dockerfile:1 FROM amazoncorretto:25.0.3-al2023 WORKDIR /deployments ARG JAR_FILE=build/libs/app.jar COPY
${JAR_FILE} app.jar ENTRYPOINT ["java", "-jar", "app.jar"] 11
Distroless # syntax=docker/dockerfile:1 FROM gcr.io/distroless/java25-debian13:nonroot WORKDIR /deployments ARG JAR_FILE=build/libs/app.jar COPY
--chown=nonroot:nonroot ${JAR_FILE} app.jar CMD ["app.jar"] 12 • JVM は Temurin • Entrypoint に `java -jar` が 指定されている
Distroless x カスタム JRE # syntax=docker/dockerfile:1 FROM amazoncorretto:25.0.3-al2023 AS build
WORKDIR /jlink RUN jlink \ --verbose \ --compress=2 \ --strip-java-debug-attributes \ --no-header-files \ --no-man-pages \ --add-modules [依存モジュール] \ --output jre-min 13 • アプリ実行に必要なモジュール のみを集めた JRE • Spring Boot アプリの 依存モジュールの調べ方は 割愛 FROM gcr.io/distroless/java-base-debian13:nonroot WORKDIR /deployments COPY --from=build --chown=nonroot:nonroot /jlink/jre-min /opt/jre-min ENV JAVA_HOME=/opt/jre-min ENV PATH=$JAVA_HOME/bin:$PATH ARG JAR_FILE=build/libs/app.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
Buildpacks x Distroless x カスタム JRE plugins { alias(libs.plugins.spring.boot) }
tasks.bootBuildImage { runImage = "gcr.io/distroless/java-base-debian13:nonroot" imageName = "distroless-jvm-examples-distroless-custom-jre-buildpack" environment = mapOf( "BP_JVM_JLINK_ENABLED" to "true", "BP_JVM_JLINK_ARGS" to "--add-modules [依存モジュール]", ) } 14 [versions] spring-boot = "4.0.6" [plugins] spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
コンテナイメージのサイズと 起動速度の比較 15
サイズの比較 16 イメージ 圧縮後サイズ corretto 265.43 MB distroless 94.62 MB
distroless-custom-jre 72.79 MB distroless-custom-jre-buildpack 87.92 MB
コンテナ実行環境での起動時間の比較 • コンテナ起動時間とイメージサイズ ◦ pull 時間 + アプリ起動時間 = コンテナ起動時間
• 実験手法 ◦ ECR + ECS Express ◦ デプロイ方式: カナリアデプロイ ▪ ベイク時間: 合計 6 分 ◦ 102 回再起動 17 引用: DevelopersIO, Classmethod, ECS Express Mode でデプロイにかかる時間を可能な限り短縮する, https://dev.classmethod.jp/articles/ecs-experss-reduce-deployment-time/
コンテナ実行環境での起動時間の比較 • 結果 18 秒 corretto Distroless Buildpacks x Distroless
x カスタム JRE Distroless x カスタム JRE • Dockerfile 形式同士: 軽量なほど起動時間が速い • サイズだけが起動時間に影響している訳ではない
Java アプリを Distroless で 動かす際にやってほしいこと 19
ローカルから docker で起動しておく • ローカルでもクラウドでも同じものを実行する ◦ The Twelve Factor App
• compose.yaml ◦ アプリ起動に必要な環境変数もまとめられる • 起動方法 ◦ Jar ファイルのビルド: gradle build ◦ コンテナ実行: docker compose up --build 20
コンテナレベルのブラックボックステスト • アプリの異常だけでなく コンテナの異常を検知できる • プラグインで自動化 ◦ テスト実行前: compose up
◦ テスト実行後: compose down 21 [versions] docker-compose = "0.17.21" [plugins] docker-compose = { id = "com.avast.gradle.docker-compose", version.ref = "docker-compose" } plugins { alias(libs.plugins.docker.compose) } dockerCompose { useComposeFiles = listOf("../compose.yaml") } tasks.test { useJUnitPlatform() mustRunAfter("composeUp") } tasks.composeDown { mustRunAfter("test") } tasks.register("integrationTest") { dependsOn("composeUp") dependsOn("test") dependsOn("composeDown") }
リモートデバッグ • ローカルでコンテナを実行してもデバッグが可能 • JRE に jdk.jdwp.agent を追加 • 5005
ポートの解放 • 環境変数 JAVA_TOOL_OPTIONS 22 services: distroless-custom-jre: build: context: ./app dockerfile: Dockerfile_distroless_custom_jre ports: - "8083:8080" - "5005:5005" environment: JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
docker compose のヘルスチェックが難しい • Dockerfile や compose.yaml のヘルスチェックは コンテナ内でコマンドを実行する •
curl がないためヘルスチェックができない • クラウドの場合は問題ないことが多いので 気にしていない 23
まとめ 24
まとめ • イメージサイズの軽量化は、これらの時間短縮につながる ◦ ローカル環境での初回 pull ◦ コンテナレジストリへの初回 push ◦
コンテナ実行環境での起動時間 • コンテナ起動時間の短縮は、 サイズだけではなくコンテナ構造も影響する • コンテナイメージを工夫する場合、 常にコンテナでアプリを起動するようにする 25
アンケートの回答お願いします 全体アンケート 26 セッション アンケート