I am using sbt-assembly to get fat jars and using sbt-docker to create and push docker images. My project is multi-module which has multiple web services, UI, database etc. Since my base docker image is big (800M), I want to create a docker image containing all the fat jars, so that I can easily test in cloud using one modest machine. I call this solution as All-FatJars-in-One (AFIO). I have trouble to build such AFIO docker image thus this post.
Suppose this multi-module project has module root and mod1, below is the build.scala:
val exeProjs = Seq(mod1)
lazy val root = Project("root", file(".")).
enablePlugins(DockerPlugin).
aggregate(exeProjs.map(_.project): _*).
dependsOn(exeProjs.map(_ % "compile->test"): _*).
settings(basicSettings: _*).
settings(
docker <<= docker dependsOn assembly,
dockerfile in docker := {
//get root artifact path like
// /home/me/root/target/scala-2.11/root-assembly-0.1-SNAPSHOT.jar
val parentArtifact = (assemblyOutputPath in assembly).value
new Dockerfile {
from("java:8")
exeProjs.map(proj => {
val projName = proj.id
// fullPathToMod1Art will be like
// /home/me/root/mod1/target/scala-2.11/mod1-assembly-0.1-SNAPSHOT.jar
fullPathToMod1Art = { NASTY parsing to get mo1 artifact }
val artifactTargetPath = s"/app/$projName/$artifact"
addRaw(fullPathArt, artifactTargetPath)
})
}
}
imageNames in docker := Seq(
ImageName("myaccount/root:v1")
)
)
lazy val mod1 = Project("mod1", file("mod1")).
enablePlugins(DockerPlugin).
settings(basicSettings: _*).
settings(
libraryDependencies ++= Seq(spray_can, spray_routing, akka_actor, junit),
docker <<= docker dependsOn assembly,
dockerfile in docker := {
val artifact = (assemblyOutputPath in assembly).value
val artifactTargetPath = s"/app/${artifact.name}"
new Dockerfile {
from("java:8")
add(artifact, artifactTargetPath)
entryPoint("java", "-jar", artifactTargetPath)
}
},
imageNames in docker := Seq(
ImageName("myaccount/mod1:v1")
)
)
Problems:
above code does not work because the root module cannot find mod1 artifact even I have verified fullPathToMod1Art is correct for the generated mod1 artifact. I specified root dependsOn mod1 by compile->test since I don't know what other configurations are better to describe the need: root's docker image creation depends on mod1 fat jar generation.
As you see, there is nasty path parsing to get mod1 artifact path in root module settings. There must be better way.
Questions:
If sbt-docker + sbt-assembly solution supports AFIO model, how to do it correctly so above two problems are solved elegantly? If they do not support, what other plugins can help?
Appreciate for any clue.