Skip to content

Commit

Permalink
optimize docker layering
Browse files Browse the repository at this point in the history
  • Loading branch information
dwickern committed Feb 10, 2025
1 parent 3216adb commit 1f8864b
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 14 deletions.
20 changes: 7 additions & 13 deletions src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,7 @@ object DockerPlugin extends AutoPlugin {
implicit val conv: FileConverter = conv0
val dockerBaseDirectory = (Docker / defaultLinuxInstallLocation).value
// Ensure this doesn't break even if the JvmPlugin isn't enabled.
var artifacts = projectDependencyArtifacts.?.value.getOrElse(Nil).map(_.data).toSet

// add the classpath jar to the project artifacts to improve layer caching as it is created by
// the ClasspathJarPlugin and is not part of the projectDependencyArtifacts
ClasspathJarPlugin.autoImport.packageJavaClasspathJar.?.value match {
case Some(p) => artifacts += p
case _ =>
}
val dependencies = (Runtime / dependencyClasspath).value.map(_.data).toSet

val oldFunction = dockerLayerGrouping.value

Expand All @@ -130,12 +123,13 @@ object DockerPlugin extends AutoPlugin {
val confDir = dockerBaseDirectory + "/conf/"

oldPartialFunction.orElse {
// bin directory contains start scripts which are containing artifacts / classpath jar,
// bin directory contains start scripts which reference artifacts / classpath jar,
// so should be together with actual artifacts
case (file, path) if artifacts(file) || path.startsWith(binDir) => 4
case (_, path) if path.startsWith(jreDir) => 3
case (_, path) if path.startsWith(libDir) => 2
case (_, path) if path.startsWith(confDir) => 1
case (_, path) if path.startsWith(jreDir) => 10
case (file, _) if dependencies(file) => 20
case (_, path) if path.startsWith(confDir) => 30
case (_, path) if path.startsWith(libDir) => 40
case (_, path) if path.startsWith(binDir) => 40
}
},
dockerAliases := {
Expand Down
39 changes: 38 additions & 1 deletion src/sbt-test/docker/test-layer-groups-playframework/build.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name := """test-layer-groups-playframework"""
name := "test-layer-groups-playframework"
organization := "com.example"

version := "1.0-SNAPSHOT"
Expand All @@ -15,3 +15,40 @@ libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1

// Adds additional packages into conf/routes
// play.sbt.routes.RoutesKeys.routesImport += "com.example.binders._"

enablePlugins(DockerPlugin, LauncherJarPlugin)

// generate a conf/application.ini
Universal / javaOptions ++= Seq("-J-Xms1024m", "-J-Xmx1024m")

TaskKey[Unit]("checkDockerLayers") := {
val layers = (Docker / dockerLayerMappings).value.groupBy(_.layerId).withDefaultValue(Nil)

val layer10 = layers(Some(10))
assert(layer10.isEmpty, "layer 10 is empty because jlink is not used")

val layer20 = layers(Some(20))
assert(
layer20.forall(_.file.getPath.startsWith(csrCacheDirectory.value.getPath)),
"layer 20 only contains external libraries"
)

val layer30 = layers(Some(30))
assert(layer30.exists(_.path == "/opt/docker/conf/conf/application.ini"), "layer 30 contains application.ini")
assert(layer30.exists(_.path == "/opt/docker/conf/conf/logback.xml"), "layer 30 contains logback.xml")

val layer40 = layers(Some(40))
assert(
layer40.exists(_.file == (Runtime / PlayKeys.playJarSansExternalized).value),
"layer 40 contains Play's -sans-externalized.jar"
)
assert(layer40.exists(_.file == PlayKeys.playPackageAssets.value), "layer 40 contains Play's -assets.jar")
assert(layer40.exists(_.file == packageJavaLauncherJar.value), "layer 40 contains launcher jar")
assert(
layer40.exists(layer => makeBashScripts.value.map(_._1).contains(layer.file)),
"layer 40 contains start scripts"
)

val layerFinal = layers(None)
assert(layerFinal.exists(_.path.startsWith("/opt/docker/share/doc/api/")), "final layer contains API docs")
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.6")
addSbtPlugin("org.foundweekends.giter8" % "sbt-giter8-scaffold" % "0.17.0")
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % sys.props("project.version"))
1 change: 1 addition & 0 deletions src/sbt-test/docker/test-layer-groups-playframework/test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
> checkDockerLayers

0 comments on commit 1f8864b

Please sign in to comment.