Tuesday, October 13, 2015

Running Play Framework applications in AWS ElasticBeanstalk as a Java application

AWS recently announced a new platform for ElasticBeanstalk to launch application, which to be frank should have been there since day1. Anyways, now, you can launch your java apps as plain simple jar. This is great news for frameworks like Dropwizard which defacto give a jar as end artifact. Same goes for any maven based project.

The Play Framework projects though are bit tedious when it comes to running them as Java apps. Here I present one way of running Play based applications in ElasticBeanstalk as a java app.

Prepping the jar


For starters, you need to move away from using activator dist to package your app. Instead you will use activator assembly.

First you will add the sbt plugin for the assembly as listed below in your project/plugins.sbt as shown below

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.0")

Now for using activator assembly, you need to modify your build.sbt a little bit.


import AssemblyKeys._
assemblySettings
assemblyJarName in assembly := "something.jar"
mainClass in assembly := Some("play.core.server.NettyServer")
fullClasspath in assembly += Attributed.blank(PlayKeys.playPackageAssets.value)


Its obvious that running assembly, you will end up with conflicting jar and config files. In this case, please add the following to your build.sbt

assemblyMergeStrategy in assembly := {
  case PathList("javax", "servlet", xs @ _*)         => MergeStrategy.first
  case PathList(ps @ _*) if ps.last endsWith ".html" => MergeStrategy.first
  case PathList(ps @ _*) if ps.last endsWith ".jar" => MergeStrategy.first
  case PathList(ps @ _*) if ps.last endsWith ".conf" => MergeStrategy.first
  case "application.conf"                            => MergeStrategy.concat
  case "unwanted.txt"                                => MergeStrategy.discard
  case x =>
     val oldStrategy = (assemblyMergeStrategy in assembly).value
  oldStrategy(x)
}

Finally you can build your Play Framework application as a jar file using following command

$ activator clean assembly


This will generate the jar inside the target/scala-2.xx folder within your project.

Now you have a jar file of your app which you can run as a standalone using java jar command.

Preparing the package

Next thing will be packaging the jar and any other sundries inside a zip folder that will be delivered as application version to elasticbeanstalk.

#!/bin/bash
rm -rf package
mkdir package
cp -r target/scala-2.xx package/target
cp -r .ebextensions package/
cp Procfile package
cd package
zip -r deploy.zip *

This zip contains a Procfile, your application jar along with any dependencies as well as .ebextensions/ folder that contains any beanstalk extension/config files.

The Procfile contents are the app name followed by the command to run it.

Instead of Procfile you can also supply a Buildfile which tells beanstalk how to build your sourcecode.

Syntax for Procfile looks as below:

webapp: java -jar target/

You can pass Java Options using the -D argument to above line. To pass any JAVA_OPTS to your app from your ElasticBeanstalk app using Configuration settings.

Running the app


You can now drop your zip file using the upload button on ElasticBeanstalk environment console. 


No comments:

Post a Comment