JavaãScalaã¨ãã£ãJVMè¨èªã®Dockerã¤ã¡ã¼ã¸ã¯ãJVMãå梱ããªããã°ãªããªãé½åã§è¥å¤§åããã¡ã§ãããç¹ã«ä½ãããªãã¦ããä¾ãã°ä¸è¬çãªamazoncorretto:21
ã®ã¤ã¡ã¼ã¸ãµã¤ãºã¯217.7 MBãããã
ããã«ããã«ãã«ãæ¸ã¿ã®JARãã¡ã¤ã«ãè¼ã£ã¦ããã®ã§ãçµæ§å¤§ãããªã£ã¦ãã¾ãã®ã ã
ããã§ãScalaã®ã³ã³ããã¤ã¡ã¼ã¸ã®ãµã¤ãºããªãã¨ãå°ããã§ããªããã¨ãèãããããã¨ãJVMã使ã£ãã¾ã¾70 MiBãããã«ç¸®ãããã¨ãã§ããã
ã³ã³ããã¤ã¡ã¼ã¸ã®ãµã¤ãºãå°ããããããã«ãä½ãããããæ¸ãã¦ãããã¡ãªã¿ã«é¡æã¨ããã¢ããªã±ã¼ã·ã§ã³ã¯ã¡ãã£ã¨ããHello, Worldãããã ãã®ãã®ã§ãã©ã¤ãã©ãªã¯Catsã«ä¾åãããã
JVM使ãç·¨
ãã«ãã¹ãã¼ã¸ãã«ããè¡ã
ã³ã³ãã¯ããªDockerã¤ã¡ã¼ã¸ã®ããã«ã¯ããã«ãã¹ãã¼ã¸ãã«ãã¯ãã¯ãå¿ é ã®å·¥ç¨ã¨ãªãã¤ã¤ããããã«ãã¹ãã¼ã¸ãã«ããè¡ããã¨ã§ãå®éã«åä½ããææç©ãä½ãããã«å¿ è¦ãªãã¡ã¤ã«ããæçµçãªã³ã³ããã¤ã¡ã¼ã¸ããåãåãããã¨ãã§ãããããã¤ã¡ã¼ã¸ãµã¤ãºãå°ããã§ããã®ã ã
è¦ããã«ãã±ãããä¸æ®µãæ¨ã¦ã¦ããã®ã¨åãã§ããä¸è¦ãªé¨åãæ¨ã¦ã¦å¿ è¦ãªé¨åã ãããå±ãããããã
Alpineãªã©ã®è»½éã©ã³ãã¼ã¤ã¡ã¼ã¸ã使ã
軽éãªã³ã³ããã«ããããã®ãã¼ã¹ã¤ã¡ã¼ã¸ã¨ããã°ãDistrolessãæåã ããããDistrolessã¯åçã©ã¤ãã©ãªãæ®ãã©å«ãã§ããããå½ç¶Javaãã¤ããªãç¡ãã®ã§å³ãããã®ãããã(javaãå ¥ã£ãdistrolessãããããããã¯ããã§çµæ§å¤§ããã¦ããããå°ãããªããªã)
ããã§ä»åã¯Alpineã使ããã¨ã«ãããAlpineã¨ããã°ãå®æãªå©ç¨ã«ã¤ãã¦è¦éãé³´ããããã¡ã§ããã£ããæè¿ã§ã¯å«ããè ã ã
ãã¶ããããçºç«¯ãªã®ã ããããããããã«å調ãã¦ããã ãã®äººéãããããã ã
ä»åã¯Alpineã®ä»£è¡¨çãªå°é·ãããªãã¡muslã使ããã¦ãããã¨ããã¾ãåé¿ã§ããã®ã§åé¡ãªããã¨ããã®ããJVMèªä½ãmuslã§ãã«ãããã¦ããã°å¾ã¯VMä¸ã§Javaãã¤ãã³ã¼ããåãã ããªã®ã§ä½ãåé¡ããªãã®ã§ããã
ããããããã§ãä»åã¯ã©ã³ãã¼ã¤ã¡ã¼ã¸ã¨ãã¦alpine:latest
ãå©ç¨ãã¦ãã(æ¬å½ã¯åºå®ããã»ãããã)ã
jlink
ãå©ç¨ãã
JVMã®ãã¤ããªããä»å±åããããã«ãããã¨ããåé¡ããªãã¨ãããããã«ãããã¼ã«ãjlink
ã§ãããããã¯JDKã«ä»å±ãããã¼ã«ã§ãã¢ããªã±ã¼ã·ã§ã³ããå¼ã°ããªãã¢ã¸ã¥ã¼ã«ãåé¤ããJVMã®ãµãã»ãããçæãããã¨ã§ãå°ããªJVMãä½ã£ã¦ããããã¤ã
ä¾ãã°java.base
以å¤ã®ã¢ã¸ã¥ã¼ã«ãå¼ã°ãã¦ããªããã¨ãããã£ãã¨ããjlink
ã¯java.base
以å¤ã®ã¢ã¸ã¥ã¼ã«ãåãæã£ããã¼ã¸ã§ã³ã®JVMããã£ã¬ã¯ããªã«åºåãã¦ããããå¾ã¯ãããDockerã¤ã¡ã¼ã¸ã«å
¥ãã¦ãJVMã¨ãã¦ä½¿ãã°ããã®ã ã
jlink
ã«é¢ãã¦ã¯ä»¥ä¸ã®è¨äºã詳ãã:
ä»åã¯ãScalaã®ãã«ããã¼ã«ã§ããsbtããjlink
ãå¼ã³åºããã©ã°ã¤ã³ã¨ãã¦sbt-native-packager
ãå©ç¨ããããã®ãã©ã°ã¤ã³ã«ã¯jlink
ãå¼ã³åºãããã®è¨å®ãéå±ããã®ã ã
ã¾ãproject/plugins.sbt
ã«ä»¥ä¸ã®ããã«è¨è¿°ãã:
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.16")
次ã«build.sbt
ã«ä»¥ä¸ã®ããã«è¨è¿°ãã:
val scala3Version = "3.3.3" enablePlugins(JlinkPlugin) lazy val root = project .in(file(".")) .settings( // ... jlinkIgnoreMissingDependency := JlinkIgnore.everything, // you should specify more preciously in production jlinkOptions += "--compress=2" )
jlinkIgnoreMissingDependency
ã¯ãããjlink
ãä¾åæ§ã解決ã§ããªãã£ããã©ããããããæå®ãããã®ã ãå®éã«ä½¿ã£ãã¨ãã誤æ¤ç¥ã ã£ãã®ã§ãããã§ã¯å
¨é¨ç¡è¦ããã¦ããã
ããã§ä»¥ä¸ã®ããã«å
¥åããã¨ãtarget/universal/stage
以ä¸ã«ã«ã¹ã¿ã ãããJVMãªã©ãåºåããã:
% sbt stage
ãããDockerã³ã³ããã«è©°ãè¾¼ãã°ããã
Dockerfile
å
¨ä½
Dockerfile
ã®å
¨ä½ãè¦ãã¨ä»¥ä¸ã®ããã«ãªã£ã¦ãã:
FROM sbtscala/scala-sbt:eclipse-temurin-alpine-21.0.2_13_1.9.9_3.4.1 AS builder WORKDIR /app COPY build.sbt . COPY src ./src COPY project ./project RUN sbt stage FROM alpine:latest AS runner RUN apk add bash COPY --from=builder /app/target/universal/stage /app/stage WORKDIR /app/stage CMD /app/stage/bin/thin-scala-container
bash
ãããããå
¥ãã¦ããã®ã¯ãstageããã¦åºåãããã©ã³ãã£ã¼ãbashåæã§è¨è¨ããã¦ããããã ã
ãã«ããã¦å®è¡ãã
ã³ã³ããããã«ãããã
% docker build -t thinscala . % docker image inspect thinscala | jq '.[0].Size' 70372447
70 MiBã¡ãã£ã¨ã«ãªã£ãã
å®è¡ããã
% % docker run --rm -it thinscala Hello world! I was compiled by Scala 3. :) List(1, 2, 3, 4, 5, 6, 7, 8, 9, 2 ...
ãããã¾ãã ãæ®éã«åãã
Scala Nativeã使ã
å½ããåã ããScala Nativeã使ãã°JVMã使ããªãã¦ãããã®ã§ããã£ã¨ã¤ã¡ã¼ã¸ãµã¤ãºãå°ããã§ããã
// project/plugins.sbt addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.17")
// build.sbt val scala3Version = "3.3.3" import scala.scalanative.build._ enablePlugins(ScalaNativePlugin) lazy val root = project .in(file(".")) .settings( name := "thin-scala-container", version := "0.1.0-SNAPSHOT", scalaVersion := scala3Version, libraryDependencies += "org.typelevel" %%% "cats-core" % "2.10.0", nativeConfig ~= { c => c.withLinkingOptions(Seq("-static")) }, nativeLTO := "thin", nativeMode := "release-fast" )
ããã§ã¯ãã·ã³ã°ã«ãã¤ããªã«ãããã¨ã§ä¾åæ§ã®åé¡ãåé¿ãã¦ãããå®ã¯Scalaãã·ã³ã°ã«ãã¤ããªãä½ããã®ã ã
ãã«ãããã«ã¯nativeLink
ãå¼ã¹ã°ããã
% sbt nativeLink
Dockerfile-native
ãä½ã£ã¦ãDockerã§ãåãããããã«ãããã·ã³ã°ã«ãã¤ããªã«ã§ãã¦ããã®ã§ãã©ã³ãã¼ã¤ã¡ã¼ã¸ã«ã¯Distrolessãå©ç¨ã§ããã
FROM sbtscala/scala-sbt:eclipse-temurin-jammy-21.0.2_13_1.9.9_3.4.1 AS builder RUN apt update -y && apt -y install clang WORKDIR /app COPY build.sbt . COPY src ./src COPY project ./project RUN sbt nativeLink FROM gcr.io/distroless/static-debian12:latest AS runner COPY --from=builder /app/target/scala-3.3.3/thin-scala-container-out /app/main WORKDIR /app CMD [ "/app/main" ]
ãããã¦ã§ããã¤ã¡ã¼ã¸ã¯6 MiBãããã«ãªãã軽ãã
% docker image inspect thinscala | jq '.[0].Size' 5930229
ããã¾ã§å°ããã§ããã¨ããããã¤ããã¼ãæ¹åã§ãããã¨ã ããããã ãScala Nativeã«ã¾ã 対å¿ãã¦ããªãã©ã¤ãã©ãªãããã®ã§ãã©ã¤ãã©ãªã«å°ã注æãå¿ è¦ã ã