Collabnix

Collabnix

How to Deploy a Play Framework Application using sbt on Docker

How to Deploy a Play Framework Application using sbt on Docker

Rohith Raju's photo
Rohith Raju
ยทJul 31, 2022ยท

5 min read

Subscribe to our newsletter and never miss any upcoming articles

Play this article

Table of contents

What is the Play Framework?

Play Framework is a high-productivity Java and Scala web application framework that integrates the components and APIs you need for modern web application development. Think of it as react but for Java and Scala . We will be mostly using Scala for our blog.

Play is based on a lightweight, stateless, web-friendly architecture. Thanks to its reactive model, based on Akka Streams, it features predictable and minimal resource consumption (CPU, memory, threads) for highly-scalable applications. Play today has an active community of more than 10,000 people, with a growing number of applications running in production all over the globe.

What is sbt? Why not use Maven for building play app?

sbt is an open-source build tool for Scala and Java projects, similar to Apache's Maven and Ant. Here's the following reason why we chose sbt over Maven :

  • It supports incremental compilation, which is comparing and compiling/building a part of the application which has been modified from that of the previous build. Which makes the build faster and saves time.
  • If you already know scala then you can extend the sbt service by using the scala code in the build file.
  • You should only use maven if you have a CI server that is well integrated with maven and also if you want to apply tight integrations without depending on external factors.

What are we going to build?

We will use a sample Play application. Let's see how to build it and run it as a Docker container.

Create a Dockerfile ๐Ÿณ

  • Step 1: Choosing an image and defining arguments for env and versions.
FROM openjdk:8-jre-alpine@sha256:f362b165b870ef129cbe730f29065ff37399c0aa8bcab3e44b51c302938c9193
USER root

ARG SCALA_VERSION=2.12.11
ARG SBT_VERSION=1.3.9
ENV SCALA_HOME=/usr/share/scala
  • Step 2: Installing Java in our image.
RUN apk update
RUN apk fetch openjdk8
RUN apk add openjdk8
ENV JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk
ENV PATH="$JAVA_HOME/bin:${PATH}"

In the above snippet, If you're wondering why we aren't using the latest java version, that's because, play only supports versions from SE 8 through SE 11, inclusive, more info here.

  • Step 3: Install Scala - 3.1.3
RUN apk add --no-cache --virtual=.build-dependencies wget ca-certificates && \
  apk add --no-cache bash && \
  cd "/tmp" && \
  wget "https://github.com/lampepfl/dotty/releases/download/3.1.3/scala3-3.1.3.tar.gz" && \
  tar xzf "scala3-3.1.3.tar.gz" && \
  mkdir "${SCALA_HOME}" && \
  rm "/tmp/scala3-3.1.3/bin/"*.bat && \
  mv "/tmp/scala3-3.1.3/bin" "/tmp/scala3-3.1.3/lib" "${SCALA_HOME}" && \
  ln -s "${SCALA_HOME}/bin/"* "/usr/bin/" && \
  apk del .build-dependencies && \
  rm -rf "/tmp/"*

From the above snippet, we first set up a virtual env and install dependencies over there. We then create a temporary directory and install scala. Then we remove the build dependencies and windows bat file. we then move and create links as required.

  • Step 4: Install sbt to build and compile Play App - Sbt-1.7.1
  RUN \
  apk add --no-cache --virtual=.build-dependencies bash curl bc ca-certificates && \
  cd "/tmp" && \
  update-ca-certificates && \
  scala -version && \
  scalac -version && \
  curl -fsL https://github.com/sbt/sbt/releases/download/v1.7.1/sbt-1.7.1.tgz | tar xfz - -C /usr/local && \
  $(mv /usr/local/sbt-launcher-packaging-1.7.1 /usr/local/sbt || true) && \
  ln -s /usr/local/sbt/bin/* /usr/local/bin/ && \
  apk del .build-dependencies && \
  rm -rf "/tmp/"*

In the above snippet, we use curl to download and install sbt and delete any pre-built build dependencies.

  • Step 5: COPY, EXPOSE and RUN
COPY. . 
EXPOSE 9000
RUN sbt compile -Dsbt.rootdir=true

Pretty straightforward. -Dsbt.rootdir=true allows sbt to run on the root directory. You can omit the Expose cmd if you want.

  • Step 6: Run sbt command during container startup
CMD [ "sbt","-Dsbt.rootdir=true", "run" ]
  • Step 7: Time to build Docker Image
docker build -t scalaApp .
=> CACHED [ 5/10] RUN java -version                                                                                                                                                                                         0.0s 
 => CACHED [ 6/10] RUN javac -version                                                                                                                                                                                        0.0s 
 => CACHED [ 7/10] RUN apk add --no-cache --virtual=.build-dependencies wget ca-certificates &&   apk add --no-cache bash &&   cd "/tmp" &&   wget "https://downloads.typesafe.com/scala/2.12.11/scala-2.12.11.tgz" &&   ta  0.0s 
 => CACHED [ 8/10] RUN   apk add --no-cache --virtual=.build-dependencies bash curl bc ca-certificates &&   cd "/tmp" &&   update-ca-certificates &&   scala -version &&   scalac -version &&   curl -fsL https://github.co  0.0s 
 => [ 9/10] COPY . .                                                                                                                                                                                                         0.4s 
 => [10/10] RUN sbt compile -Dsbt.rootdir=true                                                                                                                                                                             344.8s 
 => exporting to image                                                                                                                                                                                                       4.1s 
 => => exporting layers                                                                                                                                                                                                      4.0s 
 => => writing image sha256:5dabe621af2093f92e9fd191ce966d626a6d6582e1a3fdccba22be06928a5a2b                                                                                                                                 0.0s 
 => => naming to docker.io/library/scalaapp

Grab a cup of โ˜•

Since it's the first time building the application, sbt is going to take its own sweet time to compile the project (mine was around 5 mins ๐Ÿ˜…). Since sbt is an incremental compiler, that happens only once.

Running a Docker container

image.png Use 9000 as the port and click on run. By doing this, we are binding our port and the container's port as 9000:9000.

Voila!! โญ

Open the browser and go to http://localhost:9000/. You will be greeted with the Welcome message.

image.png

Here's the entire docker file

FROM openjdk:8-jre-alpine@sha256:f362b165b870ef129cbe730f29065ff37399c0aa8bcab3e44b51c302938c9193
USER root

ENV SCALA_HOME=/usr/share/scala

## Installing java 

RUN apk update
RUN apk fetch openjdk8
RUN apk add openjdk8
ENV JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk
ENV PATH="$JAVA_HOME/bin:${PATH}"



RUN apk add --no-cache --virtual=.build-dependencies wget ca-certificates && \
  apk add --no-cache bash && \
  cd "/tmp" && \
  wget "https://github.com/lampepfl/dotty/releases/download/3.1.3/scala3-3.1.3.tar.gz" && \
  tar xzf "scala3-3.1.3.tar.gz" && \
  mkdir "${SCALA_HOME}" && \
  rm "/tmp/scala3-3.1.3/bin/"*.bat && \
  mv "/tmp/scala3-3.1.3/bin" "/tmp/scala3-3.1.3/lib" "${SCALA_HOME}" && \
  ln -s "${SCALA_HOME}/bin/"* "/usr/bin/" && \
  apk del .build-dependencies && \
  rm -rf "/tmp/"*

RUN \
  apk add --no-cache --virtual=.build-dependencies bash curl bc ca-certificates && \
  cd "/tmp" && \
  update-ca-certificates && \
  scala -version && \
  scalac -version && \
  curl -fsL https://github.com/sbt/sbt/releases/download/v1.7.1/sbt-1.7.1.tgz | tar xfz - -C /usr/local && \
  $(mv /usr/local/sbt-launcher-packaging-1.7.1 /usr/local/sbt || true) && \
  ln -s /usr/local/sbt/bin/* /usr/local/bin/ && \
  apk del .build-dependencies && \
  rm -rf "/tmp/"*

COPY . .

EXPOSE 9000

RUN sbt compile -Dsbt.rootdir=true

CMD [ "sbt","-Dsbt.rootdir=true", "run" ]

References

Did you find this article valuable?

Support Collabnix by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
ย 
Share this