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
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.
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!