Dockerizing a Play Application

February 5, 2015 - 5 minute read -
docker play-framework groupon java

Recently I learnt how to use docker, and went ahead dockerizing a Play application which I have been developing at Groupon.

Docker is basically a kind of LXC container which provides a separate environment for your application to run. Thus we can have an App running Java 8 in a machine running Java 6, without creating any issues with the apps already running. Also, getting away from the virtualenv in Python (which I don't personally like) to switch between versions of Python and creating custom packages and eggs is possible with ease. I will start off with a new Java Play application. The code is on Github at https://github.com/hyades/docker-play. So we create a new Play application from the Java template -

[~/Playground/github]$ activator new docker-play                                                                                                                                                       

Fetching the latest list of templates...

Browse the list of templates: http://typesafe.com/activator/templates
Choose from these featured templates or enter a template name:
  1) minimal-akka-java-seed
  2) minimal-akka-scala-seed
  3) minimal-java
  4) minimal-scala
  5) play-java
  6) play-scala
(hit tab to see a list of all templates)
> 5
OK, application "docker-play" is being created using the "play-java" template.

To run "docker-play" from the command line, "cd docker-play" then:
/Users/aahuja/Playground/github/docker-play/activator run

To run the test for "docker-play" from the command line, "cd docker-play" then:
/Users/aahuja/Playground/github/docker-play/activator test

To run the Activator UI for "docker-play" from the command line, "cd docker-play" then:
/Users/aahuja/Playground/github/docker-play/activator ui

First we get docker on our system. I installed the boot2docker on my MAC. In MAC and other non-Linux OS, docker will be running inside a VirtualBox VM. In Linux it will run natively, so only a apt-get install docker or yum install docker is enough to get it running.

There are two ways of creating a container. First is open up an interactive terminal like -

[~]$ docker pull ubuntu
[~]$ docker run -i -t ubuntu /bin/bash

This will fetch a ubuntu container which will be an empty one. And then we get a prompt into the container. Here we can install whatever we want, and the finally come out and say

docker ps -l
# copy the container id
[~]$ docker commit <container-id>

The second way is a better way. It is through a Dockerfile. In the dockerfile, we can provide only the build instructions. We cannot start off any process using the Dockerfile. My Dockerfile looks like this -

# Base Image as CentOS

FROM centos 

MAINTAINER aayushahuja@gmail.com

RUN yum -y update

# Install Java 1.7

RUN yum -y install wget git unzip pwgen ca-certificates java-1.7.0-openjdk java-1.7.0-openjdk-devel

ENV PROJECT_WORKPLACE /usr/src/

RUN mkdir -p $PROJECT_WORKPLACE/activator $PROJECT_WORKPLACE/build $PROJECT_WORKPLACE/app

WORKDIR $PROJECT_WORKPLACE/activator

# Fetch Activator for Play

RUN wget http://downloads.typesafe.com/typesafe-activator/1.3.2/typesafe-activator-1.3.2.zip && \
    unzip typesafe-activator-1.3.2.zip

ENV PATH $PROJECT_WORKPLACE/activator/activator-1.3.2:$PATH

# Copy Files to Docker Container

COPY . $PROJECT_WORKPLACE/build

WORKDIR $PROJECT_WORKPLACE/build

RUN activator clean stage

RUN cp -R $PROJECT_WORKPLACE/build/target/universal/stage $PROJECT_WORKPLACE/app

EXPOSE 9000

# This Runs with docker run

CMD $PROJECT_WORKPLACE/app/stage/bin/docker-play -Dhttp.port=9000 -Dlogger.file=$PROJECT_WORKPLACE/build/logger.xml

All the commands in RUN will be run when the docker container is built. The CMD is run when the container is run. Hence it is a two step process. We also expose the port 9000 of the container. This will be used by our play application to communicate through the docker to the rest of the world! Here we install some Java into the container, and some basic things before to get our app running.

So we finally build our container.

[~]$ docker build  -t  "hyades/docker-play" .

Wait some time for all stuff to be downloaded and installed to the system. Here we use the -t option to tag the container and give it a name, which can be easily used in further steps.

Now, once the build is done, we have a container ready. But its still not running. So we now run it

[~]$ docker run -d -p 0.0.0.0:9000:9000 hyades/docker-play

The -d option will run the docker run process as a daemon, the -p option will connect to an opened port on the container. Here we connect the 9000 port of our system to the 9000 port of the container. We can check this by running

[~]$ docker ps
# get the container id of our container
[~]$ docker port <container-id>
9000/tcp -> 0.0.0.0:9000

Additionally, if we are using OSX, we should open up the boot2docker's port to OSX.

 open http://$(boot2docker ip 2>/dev/null)/

This will open up the browser for you, with an IP address. Mine looks like http://192.168.59.103/.Now, if we point to http://192.168.59.103:9000, we can see the welcome message from the Play application!

So the Play application is up and running from inside the docker container!

Comments Section

Feel free to comment on the post but keep it clean and on topic.

blog comments powered by Disqus