How to create docker images for a scala multi project with sub projects

Viewed 40

We have a scala application that uses using sbt build definition. We have multiple projects and we used sbt multi-project build definition(Build.scala). Now we are planning to dockerize the application creating containers for each project but not the entire project. I read somewhere that sbt-assembly can produce one fat jar, but this is not we want. We do not want the whole application to be containerized. We want to run separate container for each sub project. I saw some plugins, but really not sure if that is the way to go. If I could generate a jar or some other executable packaged file for each sub project and am able to run it independently, I could have this jar file copied and run it on a container with a jdk base image. Could someone suggest or guide?

1 Answers

Standard approach is to use sbt-native-packager with Docker plugin. Just enablePlugins(DockerPlugin) and configure it in every module which needs it.

// to not apply the same settings in each module manually
val sharedSettings = Seq(
  version := "0.1.0"
)

val module1 = project.in(file("project1")
  .enablePlugins(DockerPlugin)
  .settings(sharedSettings)
  .settings(
    name := "project-1"
  )

val module2 = project.in(file("project2")
  .enablePlugins(DockerPlugin)
  .settings(sharedSettings)
  .settings(
    name := "project-2"
  )

// to be able to execute docker:publish and docker:publishLocal
// on all submodules with 1 command
val root = project.in(file("."))
  .aggregate(
    module1,
    module2,
  )

The Docker plugin doesn't require building Uber JAR because by default it will copy raw .class files (including .class from dependent modules) and libraries to the image and use a script which will create classpath out of them. You can customize each part of the process (base image, tags, labels, commands etc), but try out the default setup and read the documentation.

Related