Scala’s popularity has been growing significantly in the past few years as well as Docker. A couple of weeks ago, I found myself in a situation where I had to dockerize with SBT a multi-module Scala project. While it is obvious that SBT has many advantages compared to Maven (no more freaking long pom.xml files, continuous compilation, continuous testing), its documentation is definitely not my favourite one.
What I wanted to do was to compile a multi-module project, set one of the modules as the main one, assemble it with all the dependencies needed, then add it to my docker container. My project’s structure looks like this:
SBT compile & run
With the above structure, SBT understands that I have 4 sub projects (domains, services, repositories, webapp) and a root one. By default, SBT run will try to execute this empty root project and throw on an exception because the project doesn’t contain any executable code. In my case, webapp is my main module, and I wanted it to be run as default, that’s why I added this configuration into Build.scala:
Now, webapp is run by default with SBT run
Dockerize with SBT
If you are not familiar with Docker, please check it out here. The new container technology is awesome. Plus, its documentation is truly instructive.
To dockerize with SBT my application, first I need a package of the main module with its dependencies.
There are many SBT plugins that can be used for this task. The one I chose for my project is sbt-assembly. (Similar plugins: sbt-native-package, sbt-onejar, sbt-pack)
Step 1: add the plugin to /project/plugins.sbt
addSbtPlugin(“com.eed3si9n” % “sbt-assembly” % “0.13.0”)
Step 2: tell sbt-assembly which is the main project (since I don’t want the empty root project to be assembled)
Now, I will have webapp packaged with all of its dependencies in a fat jar every time I run sbt assembly
The final step is to build a docker container. This can be done by writing a Dockerfile, or not:
Write a Dockerfile (Click here for further Dockerfile instructions) My Dockerfile looks similar to this:
$ sbt assembly
$ sbt build -t image-name /path/to/folder-that-contains-Dockerfile
Don’t want to write a Dockerfile? Use sbt-docker If you don’t want to write a Dockerfile, you can simply use the sbt-docker plugin.
Add the plugin to /project/plugin.sbt
addSbtPlugin(“se.marcuslonnberg” % “sbt-docker” % “1.2.0”)
Configure it: (optional)
$ sbt docker
The docker image is now bilt and ready to run.
NOTE: SBT 0.13.5+ is required. Older versions of SBT (which doesn’t support auto plugin) need different configuration. Please check here for more information.
By the way, if you are interested by docker, here’s some extra commands for docker that we would like to share!