Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
もう一つのビルドツール mill で作る Docker イメージ / Build docker image with mill the yet another build tool
AGAWA Koji
September 16, 2019
Programming
2
1.6k
もう一つのビルドツール mill で作る Docker イメージ / Build docker image with mill the yet another build tool
for Scala Aki Matsuri (
https://scala-aki-matsuri.connpass.com/event/142817/
)
AGAWA Koji
September 16, 2019
Tweet
Share
More Decks by AGAWA Koji
See All by AGAWA Koji
Scala + Caliban で作るGraphQL バックエンド / Making GraphQL Backend with Scala + Caliban
atty303
0
88
Scala.jsとAndroidでドメイン層を共有しよう / Scala.js and Android
atty303
0
290
Case of Ad Delivery System is Implemented by Scala and DDD
atty303
4
2.4k
ログのメトリックを取ってみる話
atty303
0
730
ADC2016: Axion meets HashiCorp
atty303
0
630
scala-native 試してみた
atty303
0
240
Why Docker?
atty303
3
160
Clientから見るFinagle
atty303
1
1.7k
Consul 入門
atty303
0
270
Other Decks in Programming
See All in Programming
GDG Seoul IO Extended 2022 - Android Compose
taehwandev
0
300
A Philosophy of Software Design 後半
yosuke_furukawa
PRO
10
2.7k
Overview of The Modern Data Stack / モダンデータスタック概論
satoshihirose
6
3.3k
Web API連携でCSRF対策がどう実装されてるか調べた / how to implements csrf-detection on Web API
yasuakiomokawa
2
330
From Java through Scala to Clojure
lagenorhynque
0
190
Reactive Java Microservices on Kubernetes with Spring and JHipster
deepu105
1
170
模組化的Swift架構(二) DDD速成
haifengkao
0
380
Treasure.map(): Functional programming in JVM-based languages
paranoidmonoid
0
130
チームでカレーを作ろう!アジャイルカレークッキング
akitotsukahara
0
780
競プロのすすめ
uya116
0
660
シェーダー氷山発掘記
logilabo
0
140
Airflowはすごいぞ!
hankehly
0
370
Featured
See All Featured
The MySQL Ecosystem @ GitHub 2015
samlambert
238
11k
From Idea to $5000 a Month in 5 Months
shpigford
373
44k
A designer walks into a library…
pauljervisheath
196
16k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
10
3.4k
Design by the Numbers
sachag
271
17k
Unsuck your backbone
ammeep
659
55k
How to Ace a Technical Interview
jacobian
265
21k
Side Projects
sachag
450
37k
Building Applications with DynamoDB
mza
83
4.7k
How GitHub Uses GitHub to Build GitHub
holman
465
280k
The Straight Up "How To Draw Better" Workshop
denniskardys
225
120k
What’s in a name? Adding method to the madness
productmarketing
11
1.6k
Transcript
͏ҰͭͷϏϧυπʔϧ mill Ͱ࡞Δ Docker Πϝʔδ Ѩ ߞ࢘ @atty303 AI tech
studio / CyberAgent, Inc. © 2019 CyberAgent, Inc. 1/33
Ѩ ߞ࢘ ιϑτΣΞΤϯδχΞ @CyberAgent, Inc. • ۀྺ 14 /
Scala ྺ 4 • ήʔϜ͕͖ (Steam ϝΠϯ) ීஈઃܭͨ͠ΓόοΫΤϯυ ΛΓͭͭɺͨ·ʹ Web ϑϩϯ τΤϯυ Android Λ৮ͬͨΓ ͠·͢ɻ © 2019 CyberAgent, Inc. 2/33
! Ϗϧυπʔϧ © 2019 CyberAgent, Inc. 3/33
2018 Scala Developer Survey 1 Which build tool are you
currently using? 2 2 https://typesafe.co1.qualtrics.com/results/public/ dHlwZXNhZmUtVVJfNlB4cWNSMXdub0liVExmLTVhZjMwZDc4MjAzMGVkMDAxNDhkOTc4 OA== 1 https://www.scala-lang.org/news/survey-2018.html © 2019 CyberAgent, Inc. 4/33
mill © 2019 CyberAgent, Inc. 5/33
Your shiny new Java/Scala build tool! • https://github.com/lihaoyi/mill • Made
by Li Hayoi • Ammonite / fastparse / utest / upickle © 2019 CyberAgent, Inc. 6/33
యܕతͳMillϏϧυઃఆ // build.sc import mill._, scalalib._ object foo extends ScalaModule
{ def scalaVersion = T("2.12.10") def scalacOptions = T(Seq( "-Ypartial-unification", )) def ivyDeps = T(Agg( ivy"com.lihaoyi::upickle:0.5.1", )) } © 2019 CyberAgent, Inc. 7/33
IntelliJ IDEA ͷΠϯϙʔτ ૢ࡞ sbt mill ॳճΠϯϙʔτ 04:07 01:45 ࠶Πϯϙʔτ
02:25 00:23 • ಉ͡ MacBook • ϓϩδΣΫτ 28 © 2019 CyberAgent, Inc. 8/33
mill ͷ֦ு import mill._, scalalib._ trait ExampleModule extends Module {
def hello = T { "Hello" } def firstName = T { "Koji" } def lastName = T { "AGAWA" } def fullName = T { s"${firstName()} ${lastName()}" } def message = T { s"${hello()}, ${fullName()}" } } object example extends ScalaModule with ExampleModule { def scalaVersion = "2.13.0" } © 2019 CyberAgent, Inc. 9/33
λεΫͷ࣮ߦ $ ./mill example.message $ Λฦ͍ͯ͠Δ͚ͩͳͷͰԿى͜Βͳ͍ © 2019 CyberAgent, Inc.
10/33
λεΫͷΛग़ྗ $ ./mill show example.message [1/1] show "Hello, Koji AGAWA"
$ © 2019 CyberAgent, Inc. 11/33
λεΫͷґଘؔ $ ./mill visualize example._ 3 $ open out/visualize/out.png 3
ExampleModule ʹؔ͢Δ෦ͷΈൈਮ © 2019 CyberAgent, Inc. 12/33
Docker © 2019 CyberAgent, Inc. 13/33
Docker • શͯͷΞϓϦ Docker Ͱཧ͍ͯ͠Δ • sbt-native-packager ͷΑ͏ʹ Docker ΠϝʔδΛ࡞
Γ͍ͨ © 2019 CyberAgent, Inc. 14/33
contrib.docker.DockerModule 4 4 http://www.lihaoyi.com/mill/page/contrib-modules.html#docker © 2019 CyberAgent, Inc. 15/33
͋ΔΜ © 2019 CyberAgent, Inc. 16/33
ίʔυྔগͳ͍ package mill package contrib.docker import mill.scalalib.JavaModule import os.Shellable.IterableShellable import
scala.collection.immutable._ trait DockerModule { outer: JavaModule => trait DockerConfig extends mill.Module { /** * Tags that should be applied to the built image * In the standard registry/repository:tag format */ def tags: T[Seq[String]] = T(List(outer.artifactName())) def labels: T[Map[String, String]] = Map.empty[String, String] def baseImage: T[String] = "gcr.io/distroless/java:latest" def pullBaseImage: T[Boolean] = T(baseImage().endsWith(":latest")) private def baseImageCacheBuster: T[(Boolean, Double)] = T.input { val pull = pullBaseImage() if(pull) (pull, Math.random()) else (pull, 0d) } def dockerfile: T[String] = T { val jarName = assembly().path.last val labelRhs = labels() .map { case (k, v) => val lineBrokenValue = v .replace("\r\n", "\\\r\n") .replace("\n", "\\\n") .replace("\r", "\\\r") s""""$k"="$lineBrokenValue"""" } .mkString(" ") val labelLine = if(labels().isEmpty) "" else s"LABEL $labelRhs" s""" |FROM ${baseImage()} |$labelLine |COPY $jarName /$jarName |ENTRYPOINT ["java", "-jar", "/$jarName"] """.stripMargin } final def build = T { val dest = T.ctx().dest val asmPath = outer.assembly().path os.copy(asmPath, dest / asmPath.last) os.write(dest / "Dockerfile", dockerfile()) val log = T.ctx().log val tagArgs = tags().flatMap(t => List("-t", t)) val (pull, _) = baseImageCacheBuster() val pullLatestBase = IterableShellable(if(pull) Some("--pull") else None) val result = os .proc("docker", "build", tagArgs, pullLatestBase, dest) .call(stdout = os.Inherit, stderr = os.Inherit) log.info(s"Docker build completed ${if(result.exitCode == 0) "successfully" else "unsuccessfully"} with ${result.exitCode}") tags() } final def push() = T.command { val tags = build() tags.foreach(t => os.proc("docker", "push", t).call(stdout = os.Inherit, stderr = os.Inherit)) } } } © 2019 CyberAgent, Inc. 17/33
͔͠͠… final def build = T { val dest =
T.ctx().dest val asmPath = outer.assembly().path os.copy(asmPath, dest / asmPath.last) os.write(dest / "Dockerfile", dockerfile()) © 2019 CyberAgent, Inc. 18/33
assembly… ͍ΑͶ… © 2019 CyberAgent, Inc. 19/33
Jib Core 5 Java library for building containers by Google
5 https://github.com/GoogleContainerTools/jib/tree/master/jib-core © 2019 CyberAgent, Inc. 20/33
Jib Core • Docker daemon ෆཁ !!! © 2019 CyberAgent,
Inc. 21/33
JavaContainerBuilder • Java ΞϓϦ͚ͷϏϧμʔΛఏڙ !!! JavaContainerBuilder .from(baseImage) .setMainClass(mainClass) .addDependencies(deps.asJava) .addProjectDependencies(projectDeps.asJava)
.addJvmFlags(jvmFlags.asJava) .toContainerBuilder .setLabels(labels.asJava) .containerize(cont) © 2019 CyberAgent, Inc. 22/33
JavaContainerBuilder JavaContainerBuilder .from("gcr.io/distroless/java:11") .setMainClass(mainClass) .addDependencies(deps.asJava) .addProjectDependencies(projectDeps.asJava) .addJvmFlags(jvmFlags.asJava) .toContainerBuilder .setLabels(labels.asJava) .containerize(cont)
© 2019 CyberAgent, Inc. 23/33
JavaContainerBuilder JavaContainerBuilder .from(baseImage) .setMainClass("glaze.progad.driver.router.Boot") .addDependencies(deps.asJava) .addProjectDependencies(projectDeps.asJava) .addJvmFlags(jvmFlags.asJava) .toContainerBuilder .setLabels(labels.asJava) .containerize(cont)
© 2019 CyberAgent, Inc. 24/33
JavaContainerBuilder JavaContainerBuilder .from(baseImage) .setMainClass(mainClass) .addDependencies(Seq("~/.cache/coursier/...").asJava) .addProjectDependencies(projectDeps.asJava) .addJvmFlags(jvmFlags.asJava) .toContainerBuilder .setLabels(labels.asJava) .containerize(cont)
© 2019 CyberAgent, Inc. 25/33
JavaContainerBuilder JavaContainerBuilder .from(baseImage) .setMainClass(mainClass) .addDependencies(deps.asJava) .addProjectDependencies(Seq("out/progad/driver/router/out.jar").asJava) .addJvmFlags(jvmFlags.asJava) .toContainerBuilder .setLabels(labels.asJava) .containerize(cont)
© 2019 CyberAgent, Inc. 26/33
JavaContainerBuilder JavaContainerBuilder .from(baseImage) .setMainClass(mainClass) .addDependencies(deps.asJava) .addProjectDependencies(projectDeps.asJava) .addJvmFlags(Seq("-XX:MaxRAMPercentage=75").asJava) .toContainerBuilder .setLabels(labels.asJava) .containerize(cont)
© 2019 CyberAgent, Inc. 27/33
JavaContainerBuilder JavaContainerBuilder .from(baseImage) .setMainClass(mainClass) .addDependencies(deps.asJava) .addProjectDependencies(projectDeps.asJava) .addJvmFlags(jvmFlags.asJava) .toContainerBuilder .setLabels(Seq("progad-router:latest").asJava) .containerize(cont)
© 2019 CyberAgent, Inc. 28/33
JavaContainerBuilder JavaContainerBuilder .from(baseImage) .setMainClass(mainClass) .addDependencies(deps.asJava) .addProjectDependencies(projectDeps.asJava) .addJvmFlags(jvmFlags.asJava) .toContainerBuilder .setLabels(labels.asJava) .containerize(containizer)
© 2019 CyberAgent, Inc. 29/33
Containizer • ϩʔΧϧͷ Docker daemon Πϯϙʔτ Containerizer.to(DockerDaemonImage.named(imageName)) • ϨδετϦϓογϡ Containerizer.to(RegistryImage.named(imageName))
© 2019 CyberAgent, Inc. 30/33
ͤ © 2019 CyberAgent, Inc. 31/33
Ռ • Jib Core ͷ͓ӄͰ mill ͷϞδϡʔϧԽ؆୯ • ۀϓϩδΣΫτʹಋೖ •
ScalaPB ϞδϡʔϧΛ sbt ൛ʹ͚ۙͮͨΓ • GenIdea Ϟδϡʔϧ͕ ScalaPB ͷੜιʔεΛ ೝࣝ͢ΔΑ͏ʹ • ޙ Pull Request ͠·͢ © 2019 CyberAgent, Inc. 32/33
ΈΜͳ mill Λ ͬͯΈΑ͏ © 2019 CyberAgent, Inc. 33/33