Playframework 2 application running on OpenShift

In my last post I have indicated that I am currently exploring the Play Framework (latest version 2.1.3) in detail. And as one of my points of interest I chose to examine some options of running an application in cloud. I was deciding between Heroku and OpenShift and the title of this post already gave away my interim decision.
The most obvious difference between those two cloud services is that OpenShift does not provide out of the box support for Play applications. But I do not consider it to be a deal breaker as long as a Play application works there.
When I started doing a light research on the subject of running Play application on OpenShift, most influential findings I found were OpenShift's blog post and Play2 OpenShift Quickstart at Github. There were others, but the basic Idea was that you can not run Play 2.x application natively (using embedded Netty and Play's command line). Long story short: you can!

Before we get started I would like to state that this post deals mostly with the configuration needed for OpenShift and Play Framework to like each other. I will not be describing in detail how to operate OpenShift or Play Framework application. But no extensive knowledge of those two is required. You do need however a basic knowledge of git version control, because that is how you communicate with OpenShift (mostly).

The basic idea

We will create an OpenShift's application and than run a Play app right from the command line just as you can do it when you are developing your Play app. That way you do not need to build any wars or compile your app into target and commit all that into a repository or anything like that.
The main goal of this post is to provide a working configuration for a simplest Play app. I have used the application you get, when you call $ play new app-name, I chose the Scala one.

OpenShift start

The first thing you need to do is to acquire an OpenShift's online account (registration here). Than you will be able to create your own application. You need to choose the DIY (Do-It-Yourself) cartridge as we will be using that one. You do not need any other cartridges for this example and you can always add more cartridges later. Once you create your application, you should be able to access its git repository.
I do recommend exploring the application's environment yourself using a ssh connection, but it is not necessary for this simple example, because my scripts use the environment's variables.

Action hooks

These hooks are scripts executed during the app's live cycle. There is a plenty of them, but the important for this example are pre_build, start and stop, you can probably guess a moment when they are executed. And this is exactly where the magic is done. If you have not done it yet, now is the time for cloning your application's git repository. The scripts are already present when you create your DIY cartridge, so you only need to modify them.

Pre build script (pre_build) is the first one executed and it handles the Play Framework installation. Firstly it checks whether Play is already present, if not it downloads the installation directly from typesafe. Than it unzips play into DATA_DIR, this is a difference to the OpenShift's blog, because we can not unzip Play directly into the home directory. Omitting that results into a lot of access/permission denied lines in a push later. The last thing the script does is removing the unnecessary zip.
#!/bin/bash
if ! [[ -d ${OPENSHIFT_DATA_DIR}play-2.1.3 ]]; then
  curl -o ${OPENSHIFT_DATA_DIR}play-2.1.3.zip http://downloads.typesafe.com/play/2.1.3/play-2.1.3.zip
  unzip ${OPENSHIFT_DATA_DIR}play-2.1.3.zip -d ${OPENSHIFT_DATA_DIR}
  rm ${OPENSHIFT_DATA_DIR}play-2.1.3.zip
fi

Starting script (start) does the heavy lifting. But as I have mentioned earlier, you do not really need to change anything, because I rely on OpenShift's variables. Details behind the APP_COMMAND line can be found in my previous post. The most important part of the line is that you are binding the Netty on that one address and one port, otherwise you would get an error java.net.SocketException: Permission denied, because you cannot bind your application to all addresses or another port than the one specified by OPENSHIFT_DIY_PORT variable (most likely 8080).
If you want to pass any other arguments to your application, here is the opportunity for that. App's output is send into play.log file located in the log directory. Than the script changes its working directory into the app's repo dir, this is the root of your application as well and here we start the Play application.
#!/bin/bash

if [[ ! $? -eq 0 ]]; then
 exit $?
fi

LOG_FILE="${OPENSHIFT_DIY_LOG_DIR}play.log"

cd ${OPENSHIFT_REPO_DIR}

APP_COMMAND="${OPENSHIFT_DATA_DIR}play-2.1.3/play \"start -Dhttp.port=${OPENSHIFT_DIY_PORT} -Dhttp.address=${OPENSHIFT_DIY_IP}\""

echo $APP_COMMAND &>> $LOG_FILE
nohup bash -c "${APP_COMMAND} &>> ${LOG_FILE} 2>&1" &> /dev/null &

The stop script (stop) only echoes the stopping event into the log and than shuts down the application using standard Play command. And again we are changing its working directory into the application's root directory.
#!/bin/bash

LOG_FILE="${OPENSHIFT_DIY_LOG_DIR}play.log"

echo "Trying to shut down app." >> $LOG_FILE

cd ${OPENSHIFT_REPO_DIR}
${OPENSHIFT_DATA_DIR}play-2.1.3/play stop
exit 0

First run

Now you should have your hooks ready to go, all you need now is to push the changes alongside with your application. I chose to modify my new Play application so it would be more enthusiastic, but a newly created Play application is a decent start. Now you need to copy all the files from the application into your repository (default .gitignore created by Play works just fine so no worries here). This way you should have all the directories of your Play app in the same directory as for example .openshift. Now commit all the changes and prepare your lucky charms for the initial push. The first push will take a time to finish, because it executes the hooks and as we know one of the hooks is downloading and uzipping the Play Framework.
If everything goes well, you will see your application running.


Do not be alarmed by 503 error that is just an OpenShift's feature. It usually takes up to  five minutes for the application to get up and running after a push. The sad thing is that the application sometimes falls asleep and you get the 503 error when attempting to access the application. It usually wakes up after a minute, but the 503 error is rather questionable.

Conclusion

The OpenShift platform allows you to do almost anything you can imagine and put into a git repository. This post is dedicated to showing one of the OpenShift's possibilities. This way you can run your Play Framework application easily in the cloud. I really like the Idea of running an application in the cloud right out of the repository.
And the OpenShift works just fine, but it is not such an out of the box solution as Heroku is. However this enables the OpenShift to be much more flexible and that is what I like about it.

Comments

  1. Hi...2 stupid questions...I'm a little noob in this...1) did you need download scala first?...2) I create my diy catridge, must I create my play app inside it?...I'm not pretty sure because I notice in the logs than I run "play start" inside openshift//app-root/data/play-2.1.3/play start .....

    I hope you can help me :D...thanks!!..

    ReplyDelete
  2. Hello,
    1) You do not need to download scala yourself, but it's libraries are downloaded by sbt build in your application upon start. And Java itself is already present on openshift cartrige.
    2) You should create your play application using $ play new inside the repository of your application, than push it to openshift.
    3) The base approach I can recommend is to use direct ssh connection to your application and experiment with commands from start/stop/pre_build scripts on your own, that way you get better overview on what is going on ... even creating test application directly on server is something you can try ... if you have play framework already present.
    4) When you succeed, you should switch to more recent version of play framework ... probably play/2.2.2/play-2.2.2.zip ( just modify all the numbers in scripts)

    Hope this helps, good luck.
    Petr

    ReplyDelete

Post a Comment

Popular posts from this blog

Automatic jsp recompile on Jboss AS 7

Ldap security for Jenkins CI

Wicket CDI integration on Jboss AS 7