Dockerize Scala sbt Application with sbt-native-packager
Functional Ops
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
- https://www.acervera.com/blog/2020/04/sbt-docker-buildx-multi-arch/#sbt-configuration
- https://softwaremill.com/how-to-build-multi-platform-docker-image-with-sbt-and-docker-buildx/
- https://medium.com/jeroen-rosenberg/lightweight-docker-containers-for-scala-apps-11b99cf1a666
- https://medium.com/rahasak/tagged/cockroachdb
- https://developer.lightbend.com/guides/openshift-deployment/lagom/building-using-sbt.html