Dockerizing Scala App

Iev Strygul
3 min readFeb 19, 2019

--

To move a Scala app in production, I needed to dockerize the app. It was the first time for me to dockerize something and I discovered many new things and pitfalls that I want to share with you.

The first step was to create a docker image of the app. However, it appeared that Scala .jar is not the same thing as Java .jar as far as it includes Scala libraries that SBT does not package by default. So if you run

java -jar app.jar

on a such .jar file, an error will be spitted out.

Therefore, I needed to find a way to include these libraries in the jar.

There are a few ways to do it and some of them are described very well here. I went for the easiest way and added the SBT Assembly plugin that allows to package all the necessary Scala libraries in a .jar file simply by running the

sbt assembly

command.

Having an appropriate .jar, I could create a Docker image. After a day of tears, I came up with this, what in the end does not seem to be very difficult:

FROM java:8WORKDIR .COPY greatEngine-assembly-0.1.jar /CMD java -jar greatEngine-assembly-0.1.jar

FROM instruction specifies the Base Image from which you are building.

WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile.

COPY (and here I spent most of the time trying to figure out what was wrong) copies new files or directories from <src> and adds them to the filesystem of the container at the path <dest>. A pitfall here is that the file is being copied from “execution context” which depends on the way how you build the image. I will come back to it a bit later.

CMD takes unix command that should be executed when the container starts

To build the image, all I needed to do is to run

docker build -t growthengine .

where ‘-t’ stands for ‘tag’ and ‘growthengine’ is the name that i wanted to give to my image.

However, my first attempts to build the image were by using another command:

docker build -t growthengine - < Dockerfile

This command is almost the same as the first one with an exception that it is being fed a Dockerfile. As the consequences, the execution context did not include other files such as my .jar file that I wanted to copy. The image was built, however, when i tried to run it, the CMD command failed, informing me that the .jar file was corrupt while it simply was not present in the image (I still wonder if there was no way to give another less confusing message). I figured it out only by building an image with ‘ls’ command to have a look at the contents of the image (dunno if there is a better approach to do it).

So the correct way to build an image was the first command with a ‘.’ in the end that points at the current folder and takes all files that are in the current folder into the execution context, allowing to copy them into the image.

Further, I needed to create a docker-compose.yml file to be able to wire the dockerized app with a mongoDb instance. But this is a story for another blog post

--

--

Iev Strygul

Forging software at the hottest Scandinavian scale-up -- Dixa. Messing with data making it useful. Love simplicity and strawberries with cream.