If you are in doubt about using Docker, Google Trends says enough about its popularity.
Until a few release ago, it was quite a hassle to run Docker. However it has become stable lately. I have been using Docker for 1.5 years and my experience has been quite amazing. I love how I can run a Docker image built on my laptop in production without any headache. Also, it’s very easy to distribute a runnable image or run someone else’s image on your machine. You need Docker insatlled on your system and you can just run the application.
In this post, we are going to create Docker image for a simple Scala application.
What is Docker?
Docker is a tool designed to run applications in an isolated environment using containers. Containerization is an OS level virtualization method to run multiple systems on a single kernel without launching an entire virtual machine. On Linux based operating systems, it is achieved using LXC (Linux Containers). Docker uses built-in Linux containment features like CGroups, Namespaces, UnionFS, chroot to run applications in the virtual environment.
LXC is an API for Linux containment features. Initially, Docker was built on top of LXC. Starting with Docker 0.9, it has been replaced with
To learn more about Docker, official documentation is a good place to start.
Docker with Scala Build
To create Docker image for a Scala application, we’ll use
sbt-native-packager focuses on creating a Docker image which can “just run” the application built by SBT.
To achieve this, a few entries have to added in
settings of project definition.
Let’s create Docker image for a simple service. Here is one that uses Akka HTTP. I just picked the first example I saw in Akka HTTP documentation. This service listens on
8080 and displays a simple hello page for
/hello path. Full code is available on GitHub.
To build Docker image for this service, project definition in
Build.scala looks like
L15 specifies the main class of the project.
L16 specifies a list of TCP ports to expose from the Docker image. Your application must be listening on one of these ports.
L17 specifies the entry point for Docker. This command will be executed when Docker container is run.
L18 specifies the repository to which the image should be pushed when
docker:publish is run.
L19 specifies the base image to be used when building Docker image for this project.
docker:publishLocal after compilation to publish the Docker image locally.
Docker with Play Application
With Play framework, project definitions are written in
build.sbt by default. Here,
main project definition looks like
L15 prevents Docker from creating images for the subprojects separately.
Build your own Baseimage
I personally prefer
phusion/baseimage which is a minimal Ubuntu baseimage. In a lot of cases, it so happens that you need some packages to run your applications. Rather than adding the code to install these packages in all build files separately, it’s easier to build an image containing all the packages and use it as baseimage for your projects.
For example, if you need Java installed, you can create a Dockerfile with following code and build your own baseimage.
- Example Code: https://github.com/neerajgangwar/dockerize-scala-app
- Official Docs: https://docs.docker.com
- sbt-native-packager: http://www.scala-sbt.org/sbt-native-packager/formats/docker.html