Dockerize Scala sbt Application with sbt-native-packager

Functional Ops

(λx.x)eranga
Effectz.AI
3 min readJul 29, 2022

--

Background

sbt uses a plugin called sbt-native-packager to allow conveniently packaging Java and Scala applications built using sbt as Docker images. This allows to package the application in native formats, like msi for Windows, dmg for macOS, deb for Debian distros, rpm for RHEL distro, universal zip,tar.gz, xz archives, docker images, graalvm native images etc. In this post, I’m gonna discuss about Docker distribution format. It will create a Docker image with all stuff necessary to execute the application from any system with Docker installed. Other things is, with sbt-native-packager we don’t have to manage custom Dockerfile’s. In here I’m using sbt-native-packager to build Docker image of the Scala sbt application and deploy it via docker-compose. Scala sbt application serve HTTP REST API and persists data on CockroachDB. The deployment contains both CockroachDB and Scala sbt application. Following figure shows the architecture of the deployment. All the source codes which related to this post available in gitlab. Please clone the repo and continue the post.

Installation

sbt-native-packager comes as sbt plugin. First I have added the sbt-native-packager dependency in to the project/plugins.sbt as below.

Then I enabled Docker and Java Application Packaging in the build.sbt file. For that, I have used two plugins which available on sbt-native-packager,1) JavaAppPackaging(will generate a folder structure with the application, dependencies, and a bash script, 2) DockerPlugin enables docker images generation. Finally I have defined some Docker related configurations, mainClass(defines Main class of the app) packageName(defines customer Docker image name), dockerExposedPorts(defines exposing ports of the Docker image), dockerEnvVars(defines env variables of Docker image), dockerExposedVolumes (defines Docker volumes). Following is the build.sbt file with these configurations and dependencies.

Build Docker

The sbt-native-packager’s Docker plugin provides many useful commands like docker:stage to generate a directory with the Dockerfile and an environment prepared for creating a Docker image. Running docker:publishLocal builds an image using the local Docker server. docker:publish to build and push an image to the configured remote repository. In here I have simply build the local Docker image with docker:publishLocal command. When building the Docker, sbt-native-packager uses the openjdk latest Docker image from DockerHub as the base image. In my case openjdk:8 has been used as the base image. If want we can customize the base image with dockerBaseImage setting for an example dockerBaseImage := "adoptopenjdk:11-jre-hotspot".

docker:publishLocal command will generates the Dockerfile inside target/docker/stage/Dockerfile. Following is the generated Dockerfile in the build.

Deployment

Once built the Docker image I have deployed it with simple docker-compose.yml deployment. As mentioned about Scala sbt application serve HTTP REST API and persists data on CockroachDB. The deployment contains both CockroachDB and Scala sbt application. First I have deployed CockroachDB and setup the database.

The deployment of the sbt application contains env variable settings, volume mappings, port mappings etc. Following is the way to deploy the sbt application and test it’s REST API.

Reference

  1. https://www.acervera.com/blog/2020/04/sbt-docker-buildx-multi-arch/#sbt-configuration
  2. https://softwaremill.com/how-to-build-multi-platform-docker-image-with-sbt-and-docker-buildx/
  3. https://medium.com/jeroen-rosenberg/lightweight-docker-containers-for-scala-apps-11b99cf1a666
  4. https://medium.com/rahasak/tagged/cockroachdb
  5. https://developer.lightbend.com/guides/openshift-deployment/lagom/building-using-sbt.html

--

--