我正在使用sbt-assembly来获取胖罐并使用sbt-docker来创建和推送docker镜像。我的项目是多模块,有多个Web服务,UI,数据库等。由于我的基础docker镜像很大(800M),我想创建一个包含所有胖罐的docker镜像,这样我就可以轻松地在云端测试一台普通的机器。我把这个解决方案称为All-FatJars-in-One(AFIO)。我很难在这篇文章中构建这样的AFIO docker图像。
假设这个多模块项目有模块root和mod1,下面是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")
)
)
问题:
上面的代码不起作用,因为根模块找不到mod1工件,即使我已经验证了fullPathToMod1Art对于生成的mod1工件是正确的。我通过compile-&gt;测试指定了根dependsOn mod1,因为我不知道其他配置更适合描述需要:root的docker图像创建依赖于mod1 fat jar生成。
如您所见,在根模块设置中有令人讨厌的路径解析来获取mod1工件路径。必须有更好的方法。
问题:
如果sbt-docker + sbt-assembly解决方案支持AFIO模型,那么如何才能正确地完成这两个问题才能优雅地解决?如果他们不支持,其他插件可以提供哪些帮助?
感谢任何线索。
答案 0 :(得分:2)
由于您要使用子项目的汇编输出,因此您应该在根项目中使docker
任务取决于子项目中的assembly
任务:
docker <<= docker.dependsOn(assembly in mod1, assembly in mod2)
目前你有docker <<= docker dependsOn assembly
会为根项目生成一个胖JAR。
您也可以为子项目获取这样的程序集输出路径:
val jarFile = (outputPath in assembly in mod1).value
希望这能解决你的问题。