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 a multi-module Scala project with SBT. 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:
COMPILE AND 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
(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 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:
In console:
$ 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)
In console:
$ sbt docker
The docker image is now built 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.