Home Education Docker Tutorial: Dockerizing Scala

Docker Tutorial: Dockerizing Scala

Author

Date

Category

Prerequisites

A working docker installation (boot2docker is fine)

Typesafe’s activator (or use ./activator found at the root of the git-repo — it will download the dependencies)

You can find/fork the sourcecode for all of the following on Github

Intro

The sbt plugin sbt-native-packager provides a really easy way to deploy your sbt project as a docker container.

In the following we will create a docker running a tiny scala helloWorld.

To use the native-packager we just add this line to your project/plugins.sbt

addSbtPlugin(“com.typesafe.sbt” % “sbt-native-packager” % “1.0.3”)

and in the build.sbt put:

enablePlugins(JavaAppPackaging)

enablePlugins(DockerPlugin)

Publishing

At this point our application is ready to run and you can deploy your docker by running

sbt docker:publishLocal

in your terminal. (This might take a while depending on how many layers you have to download)

Let’s verify the process by executing:

docker images

and we should see your newly created docker along with the base image (“java/latest”)

We can run it by executing:

docker run -it sbt-docker-example:1.0

and “Hello, world!” should be printed.

Optimizing/Customizing

There are a few settings the plugins exposes and we can override. You can find a list here.

Our current container occupies quite a lot of space ( > 800 MB) and we will try (and succeed 😛 ) to get it smaller. The current size is mostly because of the base image — “java:latest” — which is the packager’s default (it uses OpenJDK). We can override with any other image that provides a java installation.

For our example we will use frolvlad’s image which is significantly smaller and uses oracle-java. We add the following line to our build.sbt:

dockerBaseImage := “frolvlad/alpine-oraclejdk8”

Publishing the container now results in a much smaller image. However it’s broken…

sbt docker:publishLocal && docker run -it sbt-docker-example:1.0

results in:

env: can’t execute ‘bash’: No such file or directory

The native-packager depends on a working bash installation in the container. So let’s install it.

But first let’s take a look at what’s happening under the hood. We would like to know how the image is being built. Let’s take a look at the docker comands by running

sbt “show dockerCommands”

gives us:

List(Cmd(FROM,frolvlad/alpine-oraclejdk8), Cmd(WORKDIR,/opt/docker), Cmd(ADD,opt /opt), ExecCmd(RUN,List(chown, -R, daemon:daemon, .)), Cmd(USER,daemon), ExecCmd(ENTRYPOINT,List(bin/sbt-docker-example)), ExecCmd(CMD,List()))

If we blank out the scala parts (Cmd,List and ExecCmd) this looks very similar to comands we find in a Dockerfile.

We decide that the right place to install bash is right after the FROM command. Let’s override the dockerComands in our build.sbt by adding:

dockerCommands := dockerCommands.value.flatMap{
case cmd@Cmd(“FROM”,_) => List(cmd, Cmd(“RUN”, “apk update && apk add bash”))
case other => List(other)
}

We could look at the command sequence again but let’s just be bold an run the docker:

sbt docker:publishLocal && docker run -it sbt-docker-example:1.0

Et voilà, “Hello, world!” is back. And the new image size is now < 200 MB


Edit: We just published an ebook: “The Ultimate Guide to Code Review” based on a survey of 680+ developers. Enjoy!

About Codacy

Codacy is used by thousands of developers to analyze billions of lines of code every day!

Getting started is easy – and free! Just use your  GitHub, Bitbucket or Google account to sign up.

GET STARTED

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Subscribe to our newsletter

To be updated with all the latest news, offers and special announcements.

Recent posts

Introducing Pulse to help companies achieve elite engineering performance

At Codacy, we envision a future where everyone can impact the world by crafting complex software with confidence and focus at the speed of...

First QA Engineer in a Startup

This is the story of how I joined a startup as the first QA Engineer in the company.  My name is Bruno Medley, I'm a...

Is your code secure with Codacy?

If you have been in the development business, you are well aware of the fact that data breaches are a part of the development...

8 Common Software Development Mistakes and How to Avoid Them

The world of software development is fast-paced and ever-changing. The queue of feature requests never seems to shrink. With the constant demand for improvements, adherence...

The Bundling and Unbundling of the DevOps market

The DevOps market continues to grow1: The global development and operations (DevOps) market size stood at USD 3,709.1 million in 2018 and is projected to...