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
600
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
立川で超かぐや姫!について話したい / Talking Cosmic Princess Kaguya! in Tachikawa
contour_gara
1
370
AR グラス + ミニ PC で実現する新しいモバイル環境
contour_gara
0
350
TDD 実践ミニトーク
contour_gara
1
420
Spring Boot と AWS S3 を使ったアプリケーションのテスト
contour_gara
0
150
ノート PC に Linux 入れてみたけど結構良かった
contour_gara
0
3.6k
JUnit5 から Kotest へ
contour_gara
0
210
社外での学びを社内に還元したい
contour_gara
1
560
2 週間で Twitter Bot を作ってみた
contour_gara
0
1.3k
Database Rider を用いたデータベーステスト
contour_gara
0
490
Other Decks in Programming
See All in Programming
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
2.7k
20260623_Loop Engineeringで自分の分身の問い合わせBotを作る
ryugen04
0
220
地域 SRE コミュニティ最前線 - ホンマでっかSRE勉強会
tk3fftk
0
240
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
17
9.1k
関数型プログラミングのメリットって何だろう?
wanko_it
0
180
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
2
860
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
信頼性について考えてみる(SRE NEXT 2026 miniLT)
hayama17
0
190
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
3
1.5k
作るコストが小さくなった時代 幸せに働くために改めて考えたいこと 〜エンジニアとして価値を出し続けるために注視している二分野〜
yuppeeng
0
100
フィードバックで育てるAI開発
kotaminato
1
120
Featured
See All Featured
First, design no harm
axbom
PRO
2
1.2k
Marketing to machines
jonoalderson
1
5.6k
Heart Work Chapter 1 - Part 1
lfama
PRO
8
36k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
870
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
190
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
Believing is Seeing
oripsolob
1
170
Accessibility Awareness
sabderemane
1
160
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
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 セッション アンケート