SBT:如何 Dockerize 一个胖罐子?

Posted

技术标签:

【中文标题】SBT:如何 Dockerize 一个胖罐子?【英文标题】:SBT: How to Dockerize a fat jar? 【发布时间】:2017-07-25 03:22:38 【问题描述】:

我正在用一个胖 jar 构建一个 Docker 映像。我使用sbt-assembly 插件构建jar,使用sbt-native-packager 构建Docker 镜像。我对 SBT 不是很熟悉,遇到了以下问题。

    我想从docker:publish 任务中声明对assembly 任务的依赖,以便在将胖罐子添加到图像之前创建它。我按照doc 中的指示做了,但它不起作用。 assembly 在我调用它之前不会运行。

    publish := (publish dependsOn assembly).value

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

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

救命!

【问题讨论】:

【参考方案1】:

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

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 命令,因为默认添加了几个我不需要的脚本,因为我也覆盖了入口点。此外,默认的工作目录是/opt/docker,这不是我想要放置胖罐的地方。 请注意,默认命令在 sbt 控制台中由show dockerCommands 显示。

【讨论】:

是的。这是文档中的示例。一个小提示:您可以删除enablePlugins(...) 中的DockerPluginJavaAppPackaging 默认启用它。 @Muki 不完全来自文档。该文档使用已弃用的jarName,并且没有将胖罐子作为 Docker 容器的示例,而只有单独的部分。但是,是的,我从医生那里得到了这个想法。你能说是否有办法停止生成作为默认入口点的脚本?我没有包含它们,但它们仍然会在本地 opt/docker/bin 中生成。

以上是关于SBT:如何 Dockerize 一个胖罐子?的主要内容,如果未能解决你的问题,请参考以下文章

通过sbt使用java选项运行项目

使用 maven 构建一个胖罐子

是否可以用@SpringBootApplication main 制作一个带有两个弹簧启动应用程序的胖罐子

OutofMemoryError 使用 sbt 程序集创建胖 jar

如何在没有编译/检查的情况下运行“sbt run”?

装配,包括我的罐子