首页 \ 问答 \ SBT:如何Dockerize一个胖罐子?(SBT: How to Dockerize a fat jar?)

SBT:如何Dockerize一个胖罐子?(SBT: How to Dockerize a fat jar?)

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

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

    publish := (publish dependsOn assembly).value

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

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

救命!


I'm building a Docker image with a fat jar. I use the sbt-assembly plugin to build the jar, and the sbt-native-packager to build the Docker image. I'm not very familiar with SBT and am running into the following issues.

  1. I'd like to declare a dependency on the assembly task from the docker:publish task, such that the fat jar is created before it's added to the image. I did as instructed in the doc, but it's not working. assembly doesn't run until I invoke it.

    publish := (publish dependsOn assembly).value

  2. One of the steps in building the image is copying the fat jar. Since assembly plugin creates the jar in target/scala_whatever/projectname-assembly-X.X.X.jar, I need to know the exact scala_whatever and the jar name. assembly seems to have a key assemblyJarName but I'm not sure how to access it. I tried the following which fails.

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

Help!

更新时间:2023-02-04 09:02

最满意答案

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

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 ,这不是我想要放入胖罐的地方。 请注意,默认命令由sbt控制台中的show dockerCommands


Answering my own questions, the following works:

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")
)

I completely overwrite the docker commands because the defaults add couple of scripts that I don't need because I overwrite the entrypoint as well. Also, the default workdir is /opt/docker which is not where I want to put the fat jar. Note that the default commands are shown by show dockerCommands in sbt console.

相关问答

更多
  • 在Maven中,您在POM中定义依赖关系的顺序非常重要。 如果按照正确的顺序列出它们,则应该按照该顺序将它们添加到jar中,并且文件中的哪个类更高,这是首先加载的那个类。 如果您将构建多个jar包中的运行时类路径,那么再次,这是将jar放入正确顺序的问题。 I think that there's another way. I can wrap this library jar in its own custom classloader URLClassLoader c1 = new URLClassLoa ...
  • 首先,您需要了解为什么会收到此警告。 Maven约定是一个项目应该创建一个主要工件。 对于包装jar的项目,主要工件是maven-jar-plugin 。 此插件仅将JAR包含在项目中包含的类中。 一个项目最终可以生成其他工件,这些工件将通过其分类器与主工件区分开来: 除了主要工件之外,还可以添加附加到Maven项目的其他文件。 这种附加的字段可以由其分类器识别和访问。 分类器是将附加到主工件名称的标识符。 那么当你想创造一个超级罐时会发生什么? 不知何故,你的项目需要生成两个罐子。 主要的是一个包含项目类 ...
  • 胖罐子是jar,它包含所有图书馆的类,您的项目所依赖的,当然还有当前项目的类。 在不同的构建系统中,fat jar的创建方式不同,例如,在Gradle中,将使用( 指令 )创建它: task fatJar(type: Jar) { manifest { attributes 'Main-Class': 'com.example.Main' } baseName = project.name + '-all' from { configurations.comp ...
  • 嗯......没关系。 我们使用ssh任务发布将.jar移动到目标Linux服务器。 作为该任务的一部分,我们将所有Windows文件结尾转换为Unix文件结尾,但这应该仅针对文本文件进行。 我们无意中将相同的命令应用于.jar文件。 不要那样做。 Ummmm... never mind. We were using a publish with ssh task to move the .jar to our destination Linux server. As part of that task, ...
  • 最后我完全跳过使用IntelliJ IDEA,以避免在我的全球理解中产生噪音:) 我开始阅读官方的SBT教程 。 我使用以下文件结构创建了我的项目: my-project/project/assembly.sbt my-project/src/main/scala/myPackage/MyMainObject.scala my-project/build.sbt 在我的assembly.sbt文件中添加了sbt-assembly 插件 。 让我建立一个胖JAR: addSbtPlugin("com.eed ...
  • 找到答案。 将以下内容添加到您的build.sbt项目设置中 // add this on top of file import com.typesafe.sbt.SbtNativePackager._ // add this to project settings mappings in Universal := { // universalMappings: Seq[(File,String)] val universalMappings = (mappings in Universal).v ...
  • 问题出在SBT合并策略上,我用这个策略来解决问题。 assemblyMergeStrategy in assembly := { case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard case _ => MergeStrategy.first } The problem was with SBT merge strategy, I used this strategy to solve the problem. asse ...
  • 你需要的是一个可执行的jar,它不仅包含你的类,还包含你所有依赖的类。 为此,您可以使用Maven Assembly Plugin 。 请参阅下面的示例代码。 [...] [...] maven-assembly-plugin 3.0.0
  • 请记住将sbt程序集插件添加到项目中。 这不是默认命令。 用Spark建造一个胖罐子起初有点棘手,但它并不是黑魔法。 而且这也是实现你想做的事情的正确方法。 按照教程,你会很好: http://blog.prabeeshk.com/blog/2014/04/08/creating-uber-jar-for-spark-project-using-sbt-assembly/ Remember to add the sbt assembly plugin to your project. It's not a ...
  • 回答我自己的问题,以下工作: enablePlugins(JavaAppPackaging, DockerPlugin) assemblyMergeStrategy in assembly := { case x => { val oldStrategy = (assemblyMergeStrategy in assembly).value val strategy = oldStrategy(x) if (strategy == MergeStrategy.deduplica ...

相关文章

更多

最新问答

更多
  • 在csproj中使用appdata环境变量(Use appdata environment variable in csproj)
  • 从背景返回后,Skobbler Map崩溃(Skobbler Map crashes after returning from background)
  • 如何保持对绑定服务的轮询?(How to keep polling a bound service?)
  • ASP.NET单选按钮jQuery处理(ASP.NET radio button jQuery handling)
  • Linux上的FORTRAN图形库(FORTRAN graphic library on Linux)
  • 我们如何根据索引更新dynamodb表(不基于primary has和range key)(how can we update dynamodb table based on index(not based on primary has and range key))
  • 功能包装避免重复(wrap of functions avoid duplicating)
  • Android BroadcastReceiver和Activity.onPause()(Android BroadcastReceiver and Activity.onPause())
  • 无法使用phonegap 2.4在Android上播放录音(unable to play audio recordings on android using phonegap 2.4)
  • VS2015 + Resharper:不要使用C#6(VS2015 + Resharper: Don't use C#6)
  • 大学电脑四级对初学者来说要多久能过
  • 特殊字符删除?(Special characters remove?)
  • Android视频教程现在网上的都比较零散呢?有些太坑爹了,感觉老师就是在想当然的讲
  • 计算同一个表中不同行之间的差异[重复](Calculate delta's between different rows in same table [duplicate])
  • Javaweb开发,技术路线是什么?该怎么写?
  • JavaScript只在php代码中执行一次(JavaScript only executes once inside php code)
  • 不兼容的字符编码:ASCII-8BIT和UTF-8(incompatible character encodings: ASCII-8BIT and UTF-8)
  • Clojure(加载文件)给出错误(Clojure (load-file) gives an error)
  • 为具有瞬态scala依赖性的spring-xd项目优化gradle(Optimize gradle for spring-xd project with transient scala dependency)
  • 如何才能在Alpha测试模式下发布我的应用程序?(How can I publish my app in Alpha test mode only?)
  • “没有为此目标安装系统映像”Xamarin AVD Manager(“No system images installed for this target” Xamarin AVD Manager)
  • maven中的Scalatest:JUnit结果(Scalatest in maven: JUnit results)
  • 使用android SDK将文件直接上传到存储桶中的文件夹(Upload a file directly to a folder in bucket using android SDK)
  • 是否应将plists导入CoreData?(Should plists be imported to CoreData?)
  • java.lang.reflect.InvocationTargetException JavaFX TableView(java.lang.reflect.InvocationTargetException JavaFX TableView)
  • 根据唯一列值动态创建多个子集(Dynamically create multiple subsets based on unique column values)
  • 使用CSS可以使HTML锚标签不可点击/可链接吗?(Is it possible to make an HTML anchor tag not clickable/linkable using CSS?)
  • 嵌套的模板可能性(Nested template possibilities)
  • 任何方式在iOS7 +上以编程方式打开蓝牙(Any way to turn on bluetooth programmatically on iOS7+)
  • 如何为给定的SQL查询编写JPA查询(How I can write JPA query for given SQL query)