SBT:如何 Dockerize 一个 fat jar?

SBT: How to Dockerize a fat jar?

我正在构建一个带有胖罐的 Docker 图像。我使用 sbt-assembly 插件构建 jar,并使用 sbt-native-packager 构建 Docker 图像。我对 SBT 不是很熟悉,正在 运行 关注以下问题。

  1. 我想从 docker:publish 任务中声明对 assembly 任务的依赖,以便在将 fat jar 添加到图像之前创建它。我按照 doc 中的说明进行了操作,但它不起作用。 assembly 在我调用它之前不会 运行。

    publish := (publish dependsOn assembly).value

  2. 构建映像的步骤之一是复制 fat jar。由于程序集插件在 target/scala_whatever/projectname-assembly-X.X.X.jar 中创建了 jar,我需要知道确切的 scala_whatever 和 jar 名称。 assembly 似乎有一个键 assemblyJarName 但我不确定如何访问它。我尝试了以下但失败了。

    Cmd("COPY", "target/scala*/*.jar /app.jar")

求助!

回答我自己的问题,以下作品:

enablePlugins(JavaAppPackaging, DockerPlugin)

assemblyMergeStrategy in assembly := {
  case x => {
    val oldStrategy = (assemblyMergeStrategy in assembly).value
    val strategy = oldStrategy(x)
    if (strategy == MergeStrategy.deduplicate)
      MergeStrategy.first
    else strategy
  }
}

// Remove all jar mappings in universal and append the fat jar
mappings in Universal := {
  val universalMappings = (mappings in Universal).value
  val fatJar = (assembly in Compile).value
  val filtered = universalMappings.filter {
    case (file, name) => !name.endsWith(".jar")
  }
  filtered :+ (fatJar -> ("lib/" + fatJar.getName))
}

dockerRepository := Some("username")

import com.typesafe.sbt.packager.docker.{Cmd, ExecCmd}
dockerCommands := Seq(
  Cmd("FROM", "username/spark:2.1.0"),
  Cmd("WORKDIR", "/"),
  Cmd("COPY", "opt/docker/lib/*.jar", "/app.jar"),
  ExecCmd("ENTRYPOINT", "/opt/spark/bin/spark-submit", "/app.jar")
)

我完全覆盖了 docker 命令,因为默认添加了几个我不需要的脚本,因为我也覆盖了入口点。另外,默认的 workdir 是 /opt/docker ,这不是我想要放置 fat jar 的地方。 请注意,默认命令在 sbt 控制台中显示为 show dockerCommands