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
20250613-SSKMvol.15
Search
diostray
June 16, 2025
Programming
340
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
20250613-SSKMvol.15
diostray
June 16, 2025
More Decks by diostray
See All by diostray
20220210-kotlin-serverside-meetup
diostray
0
390
20210518_shikujiri_justincase
diostray
0
290
20191219-react-lightning-talk
diostray
0
300
Other Decks in Programming
See All in Programming
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.3k
typoなんかねぇよ
raspython3
0
580
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
300
Cloudflare is Agents
chimame
0
180
My Marp Sample
sinoue0108
0
120
AIと壁打ちしながら進めるコスト管理
fufuhu
2
1.8k
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
7.8k
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
7
2.2k
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
550
VibeCodingからAgenticWorkflowへ
starfish719
0
900
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
240
Loosening the Reins: Go Generics Get More Flexible
kuro_kurorrr
0
340
Featured
See All Featured
A Modern Web Designer's Workflow
chriscoyier
698
190k
Rails Girls Zürich Keynote
gr2m
96
14k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
RailsConf 2023
tenderlove
30
1.5k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
300
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
45k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
3
1.1k
The Cost Of JavaScript in 2023
addyosmani
55
10k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
480
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
420
Transcript
Buildpacks について ServerSide Kotlin Meetup vol.15 2025/6/13 株式会社 justInCaseTechnologies 1
2 はじめに
3 自己紹介: 小佐野 洋 (OSANO, Hiroshi) Full Stack Engineer (自称)
• Androidアプリ → Webフロント → バックエンドのテックリード → 技術責任者 • インフラ構築〜バックエンド〜Webフロント / モバイルアプリ ちょっとわかる ◦ バックエンドが一番長いし、得意 長いことやってきたのは Java / JavaScript • Kotlinはいいぞ (大声) • Android Jetpackもいいぞ • TypeScript もいいぞ • C#はいいぞ (小声)
4 会社紹介: justInCaseTechnologies Tech Stacks Web frontend Backend ▪ React
▪ TypeScript ▪ Vercel (Next.js) Infrastructure ▪ Kotlin ▪ Spring Framework ▪ Python (ごく一部) ▪ AWS ▪ ECS (fargate) ▪ CDK ▪ Datadog 助けられ、助ける喜びを、すべての人へ。
5 会社紹介: justInCaseTechnologies Tech Stacks Web frontend Backend ▪ React
▪ TypeScript ▪ Vercel (Next.js) Infrastructure ▪ Kotlin ▪ Spring Framework ▪ Python (ごく一部) ▪ AWS ▪ ECS (fargate) ▪ CDK ▪ Datadog 助けられ、助ける喜びを、すべての人へ。
6 そういえば 2025年の KotlinConf で戦略的提携パートナーシップのニュースが出ましたね!
7 コンテナ化、めんどくさくないですか?
• アプリケーションビルドのツールチェーン (gradle) やコマンドとうまく組み合わせないといけない ◦ jar 化の単位 (uber jar) は?ライブラリはどういれる?
◦ ビルドするところは Dockerfile の中? • Dockerfile 自体のメンテナンスが必要 ◦ ベースイメージってなんだっけ?何が入ってる? ▪ たまーーーーーにベースイメージが変わってひどい目にあった ◦ マルチステージビルド用の記述がまぁめんどくさい ▪ docker の layer に何を含める?それがどうキャッシュされる? 8 コンテナ化、結構めんどくさい (個人の感想です)
• アプリケーションビルドのツールチェーン (gradle) やコマンドとうまく組み合わせないといけない ◦ jar 化の単位 (uber jar) は?ライブラリはどういれる?
◦ ビルドするところは Dockerfile の中? • Dockerfile 自体のメンテナンスが必要 ◦ ベースイメージってなんだっけ?何が入ってる? ▪ たまーーーーーにベースイメージが変わってひどい目にあった ◦ マルチステージビルド用の記述がまぁめんどくさい ▪ docker の layer に何を含める?それがどうキャッシュされる? 9 コンテナ化、結構めんどくさい (個人の感想です) アプリケーションを作るようにイメージも作りたい!!!!! それ、あるよ (buildpacks)
10 はじめに〜今日話すこと SpringBoot アプリケーションの docker イメージの作成は gradle コマンドが提供されています その gradle
コマンドの中身を深掘りしていくのが目的です Docker イメージ作成のログ (例) === [Container] 2025/06/07 10:06:15.182670 Running command ./gradlew :console:bootBuildImage --imageName=joinsure-policy-console:$IMAGE_TAG --runImage=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_RUN_IMAGE_TAG --builder=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_BUILDER_IMAGE_TAG Starting a Gradle Daemon (subsequent builds will be faster) > Task :console:checkKotlinGradlePluginConfigurationErrors > Task :console:compileJava NO-SOURCE > Task :console:classes > Task :console:resolveMainClassName > Task :console:bootJar > Task :console:bootBuildImage Building image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' 〜中略〜 Successfully built image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' BUILD SUCCESSFUL in 2m 58s 13 actionable tasks: 12 executed, 1 from cache
11 はじめに〜今日話すこと Docker イメージ作成のログ (例) === [Container] 2025/06/07 10:06:15.182670 Running
command ./gradlew :console:bootBuildImage --imageName=joinsure-policy-console:$IMAGE_TAG --runImage=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_RUN_IMAGE_TAG --builder=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_BUILDER_IMAGE_TAG Starting a Gradle Daemon (subsequent builds will be faster) > Task :console:checkKotlinGradlePluginConfigurationErrors > Task :console:compileJava NO-SOURCE > Task :console:classes > Task :console:resolveMainClassName > Task :console:bootJar > Task :console:bootBuildImage Building image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' 〜中略〜 Successfully built image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' BUILD SUCCESSFUL in 2m 58s 13 actionable tasks: 12 executed, 1 from cache これが docker イメージを作成する gradle コマンド (引数は後で説明します) SpringBoot アプリケーションの docker イメージの作成は gradle コマンドが提供されています その gradle コマンドの中身を深掘りしていくのが目的です
12 はじめに〜今日話すこと Docker イメージ作成のログ (例) === [Container] 2025/06/07 10:06:15.182670 Running
command ./gradlew :console:bootBuildImage --imageName=joinsure-policy-console:$IMAGE_TAG --runImage=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_RUN_IMAGE_TAG --builder=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_BUILDER_IMAGE_TAG Starting a Gradle Daemon (subsequent builds will be faster) > Task :console:checkKotlinGradlePluginConfigurationErrors > Task :console:compileJava NO-SOURCE > Task :console:classes > Task :console:resolveMainClassName > Task :console:bootJar > Task :console:bootBuildImage Building image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' 〜中略〜 Successfully built image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' BUILD SUCCESSFUL in 2m 58s 13 actionable tasks: 12 executed, 1 from cache これが docker イメージを作成する gradle コマンド (引数は後で説明します) 中略部分も後で説明します SpringBoot アプリケーションの docker イメージの作成は gradle コマンドが提供されています その gradle コマンドの中身を深掘りしていくのが目的です
13 はじめに〜今日話すこと gradle のコマンド「bootBuildImage」は gradle のプラグイン「org.springframework.boot (*1)」が提供しているコマンド (*2) です このコマンドは内部で
CloudNative Buildpacks という技術を用いて docker イメージを作成しています 重要なポイントは Dockerfile が GitHub リポジトリにも、 docker イメージをビルドするところにも存在しない点です この機能を提供しているのが CloudNative Buildpacks です 「Dockerfile をプログラムで生成している」と言い換えてもいいです *1: https://plugins.gradle.org/plugin/org.springframework.boot *2: https://spring.pleiades.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#build-image
14 (CloudNative) Buildpacks とは
15 CloudNative Buildpacks とは 〜歴史編 画像は https://buildpacks.io/ より引用
16 CloudNative Buildpacks とは 〜歴史編 画像は https://buildpacks.io/ より引用 2011年に Heroku
が開発 Heroku = PaaS ベンダ ここでの名前が buildpacks だった https://jp.heroku.com/elements/buildpacks
17 CloudNative Buildpacks とは 〜歴史編 画像は https://buildpacks.io/ より引用 Pivotal が
Heroku 用の buildpacks を Heroku 以外の PaaS 用に開発 Pivotal = PaaS ベンダ (Cloud Foundry)
18 CloudNative Buildpacks とは 〜歴史編 画像は https://buildpacks.io/ より引用 2018年にPivotal と
Heroku が buildpacks を Cloud Native Computing Foundation (CNCF) に寄贈 CNCF = Kubernetes 等を保有する開発組織
19 CloudNative Buildpacks とは 〜機能編 CloudNative Buildpacks を理解する上で重要なキーワード builder buildpack
20 CloudNative Buildpacks とは 〜builderとは? コンテナ化をするためのコンテナイメージ [重要] アプリケーションのベースイメージではない = Dockerfile
の “FROM” に指定するコンテナではないです [重要] ざっくり言うとアプリケーションイメージを作るためのイメージです。この中にアプリケーションをビルドしたりする時 に必要なパッケージとかを入れます。 Docker イメージ作成のログ (例) === [Container] 2025/06/07 10:06:15.182670 Running command ./gradlew :console:bootBuildImage --imageName=joinsure-policy-console:$IMAGE_TAG --runImage=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_RUN_IMAGE_TAG --builder=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_BUILDER_IMAGE_TAG Starting a Gradle Daemon (subsequent builds will be faster) > Task :console:checkKotlinGradlePluginConfigurationErrors > Task :console:compileJava NO-SOURCE > Task :console:classes > Task :console:resolveMainClassName > Task :console:bootJar > Task :console:bootBuildImage Building image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' 〜中略〜 Successfully built image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' BUILD SUCCESSFUL in 2m 58s 13 actionable tasks: 12 executed, 1 from cache builder を指定する引数
21 CloudNative Buildpacks とは 〜builderとは? Docker イメージ作成のログ (例) === [Container]
2025/06/07 10:06:15.182670 Running command ./gradlew :console:bootBuildImage --imageName=joinsure-policy-console:$IMAGE_TAG --runImage=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_RUN_IMAGE_TAG --builder=$CUSTOM_RUN_REPOSITORY_URI:$CUSTOM_BUILDER_IMAGE_TAG Starting a Gradle Daemon (subsequent builds will be faster) > Task :console:checkKotlinGradlePluginConfigurationErrors > Task :console:compileJava NO-SOURCE > Task :console:classes > Task :console:resolveMainClassName > Task :console:bootJar > Task :console:bootBuildImage Building image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' 〜中略〜 Successfully built image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' BUILD SUCCESSFUL in 2m 58s 13 actionable tasks: 12 executed, 1 from cache こっちがアプリケーションのベース イメージを指定する引数 コンテナ化をするためのコンテナイメージ [重要] アプリケーションのベースイメージではない = Dockerfile の “FROM” に指定するコンテナではないです [重要] ざっくり言うとアプリケーションイメージを作るためのイメージです。この中にアプリケーションをビルドしたりする時 に必要なパッケージとかを入れます。
22 CloudNative Buildpacks とは 〜buildpackとは? Docker イメージ作成のログ (例) === >
Task :console:bootBuildImage Building image 'docker.io/library/joinsure-policy-console:a6e843847c73565f2b4737d13442cb00361cfa80-1749290775' 〜中略〜 > Running detector [detector] target distro name/version labels not found, reading /etc/os-release file [detector] 6 of 26 buildpacks participating [detector] paketo-buildpacks/ca-certificates 3.9.1 [detector] paketo-buildpacks/bellsoft-liberica 11.0.5 [detector] paketo-buildpacks/syft 2.8.0 [detector] paketo-buildpacks/executable-jar 6.12.1 [detector] paketo-buildpacks/dist-zip 5.9.1 [detector] paketo-buildpacks/spring-boot 5.32.1 > Running restorer > Running builder [builder] target distro name/version labels not found, reading /etc/os-release file 〜後略〜 アプリケーションイメージを作る時 に追加する buildpack を検出してい るところ アプリケーションイメージを作る時に組み込むもの ざっくり言うとコンテナイメージの Layer を作るものをパッケージしたもの
Docker イメージ作成のログ (例) === > Running builder [builder] target distro
name/version labels not found, reading /etc/os-release file [builder] [builder] Paketo Buildpack for CA Certificates 3.9.1 〜略〜 [builder] [builder] Paketo Buildpack for BellSoft Liberica 11.0.5 〜略〜 [builder] [builder] Paketo Buildpack for Syft 2.8.0 〜略〜 [builder] [builder] Paketo Buildpack for Executable JAR 6.12.1 〜略〜 [builder] [builder] Paketo Buildpack for Spring Boot 5.32.1 〜略〜 > Running exporter [exporter] Adding layer 'paketo-buildpacks/ca-certificates:helper' 〜後略〜 23 CloudNative Buildpacks とは 〜buildpackとは? アプリケーションイメージを作る時に組み込むもの ざっくり言うとコンテナイメージの Layer と、 Layer を作るためのもの アプリケーションイメージを作る時 にそれぞれの buildpack が反応して いるところ buildpack ごとにやることが違う 環境変数を変更したり、環境変数に よって Layer の中身を変えたりする それぞれの buildpack が作成した layer を合成してアプリケーションイ メージにしているところ
24 Buildpacks 実装編
25 ターミナルから実行できる “pack” という cli が提供されています (Go 製) Google Cloud
Platform はこっちを使っている模様 • https://github.com/buildpacks/pack/ 参考)buildpack 実装編
26 SpringBoot の gradle プラグインはこのあたりに実装されてます “pack” cli を利用しておらず、独自実装しています • https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot
-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/JavaPluginAction.java#L191 ◦ war の場合は別ファイル • https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot -gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.java ◦ “bootBuildImage” コマンドの中身 (主にコマンドライン引数) • https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot -buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/Builder.java ◦ “bootBuildImage” コマンドの中身 (主にアプリケーションイメージのビルドを実行するところ) 参考)buildpack 実装編