RUN@cloud » Play Framework

Play Framework

Last modified by Michael Neale on 2013/11/05 00:21

CloudBees includes first-class support for running Play! applications in the Cloud.

  • Easy deployment of Play! apps to RUN@cloud
  • Cloud-based databases (RDBMS, MongoDB, CouchDB etc)
  • Continuous Integration/deployment for Play! with Jenkins
  • GIT source code repositories for team collaboration
  • Play runs in production mode, using "dist", as recommended

To get "git push" style deployment, run the clickstart that sets up the above in one click. This will set up a play2 starter app (we try to keep it up to date - easy to update) websocket ready, with a play/sbt build/test - a good place for a new app. Otherwise, read on.

I am in a hurry and I already have a play app! How to deploy it?

If you have a play app and a cloudbees account - this is quite simple - you don't need to change your app at all: 

# Run dist - via play or sbt command - doesn't matter:
play dist

# note the zip generated from the previous step
bees app:deploy -t play2 -R java_version=1.7 target/universal/yourapp.zip

If you don't have the bees command line tool - get it from here. This uses the play clickstack.

First step: create a Play2.x application from scratch

You can skip this step if you have an existing application.

$ play new myPlayApp
       _            _
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/
            
play! http://www.playframework.org

The new application will be created in /Users/spike/webapps/myPlayApp

What is the application name?
> myPlayApp

Which template do you want to use for this new application?

  1 - Create a simple Scala application
  2 - Create a simple Java application
  3 - Create an empty project

> 1

OK, application myPlayApp is created.

Once the application has been created you can use the play command again to enter the Play 2.0 console .  You can then use the start command to launch your application for local development.

$ cd myPlayApp
$ play start
Play server process ID is 72021
[info] play - Application started (Prod)
[info] play - Listening for HTTP on port 9000...

Deploying a Play2 application

There are a few ways you can deploy:

  • Via git push - with the clickstart
  • Via a plugin: play cloudbees-deploy
  • Via the cloudbees SDK: bees app:deploy

Using the play (sbt) plugin

The play plugin means you can run play cloudbees-deploy right from inside your project - no other tools needed. This will package up your application for you and deploy it directly to cloudbees.

Follow the instructions here to add it to your Build.scala and plugins.sbt files in your project.

Using the Cloudbees SDK

Another way to deploy to CloudBees is to export the application as a Play Distribution file and then deploy the app with our Play2 ClickStack. This is what is used by the Play2 Clickstart currently for you: 

$ play dist
$ bees app:deploy -a APP_ID -t play2  dist/APP_NAME-VERSION.zip -R java_version=1.7

Alternatively, you may also stage, zip your project directory and then deploy, it's up to you and the ClickStack will sniff the contents of the zip file to know how to handle your application.

$ play stage
$ zip ../playapp.zip .
$ bees app:deploy -a APP_ID -t play2 ../playapp.zip

Using the Play2 ClickStart

The Play2 clickstart currently uses our Play2 ClickStack, which is handling Play2 apps natively - this will setup a private git repo, a Jenkins build pipeline, be websocket ready, run tests and more. You can customise the app once it is created, of course.

Websockets

With Play2 - you will probably want to use websockets - you can with cloudbees. 

To enable you will need the CloudBees SDK: 

bees app:proxy:update -a yourAppId httpVersion=1.1

You only need to do this once for your application.

CloudBees Databases

The CloudBees database service can be used from your play application, by doing the following:

  • Create a database (you can also do this from the UI if you like)
    bees db:create YOUR_DB_NAME -u YOUR_DB_USERNAME -p YOUR_DB_PASSWORD
  • Edit your apps database configuration. Tip: use "bees config:set" command to store credentials to anything sensitive - you can then refer to them from your application.conf file as ${config_name} - no secrets in source code!

Your configuration should look like this: 

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://HOST/DBNAME"
db.default.user=${DB_USER}
db.default.pass=${PASSWORD}
db.default.extendedProfile=scala.slick.driver.MySQLDriver
db.default.partitionCount=1
db.default.maxConnectionAge=1 minute
db.default.connectionTimeout=10000
db.default.maxConnectionsPerPartition=2
db.default.minConnectionsPerPartition=2

The MySQL driver will also be needed, add this to your project Build.scala config:

"com.typesafe.slick" %% "slick" % "1.0.0",
    "mysql" % "mysql-connector-java" % "5.1.21",

You then set your database name, password etc via: bees config:set DB_USER=user here  - so you don't have to store passwords in your config.

Note you can also bind databases to an application (and other things, like MongoDB) via bindings which will provide environment variables you can refer to in your config, as an alternative approach.

[Learn more about using CloudBees Databases]

MongoDB

CloudBees offer MongoDB via the mongohq hosted service (along with many other services). 

Firstly - pick a plan and subscribe. The free one is fine. 

Then create a database (either from the UI, or with the command below): 

 bees mongohq:create -a michaelnealeclickstart4 mydb1 plan=sandbox

You can then use this database in your application.

Configuration Variables and Play

You can use the CloudBees SDK and the "bees config:set" commands to set name value pairs that will be provided to your application at runtime (they are stored encrypted). To access these - you can use ${var_name} in your application.conf file - just like environment variables.

Loading an Alternative Play Configuration File

Play allows you to load an alternative configuration using a -Dconfig.resource=CONF_FILENAME system property.  You app will then look for the alternative configuration file in the application classpath (you usually provide these alternative configuration files into your application conf/ directory before packaging).

To customize this value on CloudBees, you can use the Bees SDK:

bees config:set -a APPID config.resource=myalt.conf

Note: you'll need to restart your app for this config param to be applied

Private mode

If you want to have your application run in a "private mode" where only those with the password can access it (ie, during development) - you can use the Global interceptor here - simply copy that into your controllers directory and follow the instructions.

Loading config files in production

Play applications run on CloudBees in production mode - using the "dist" packaged version of the Play application. If you have files in your project, you need to know to load them from the classpath not from the "getFile" methods - those getFile methods may work in development time, but in production play apps, the files will not be there. 

For example, if you have a file called "mydata.json" in the conf directory, you access that as follows: 

Play.application.resourceAsStream("mydata.json")

Note it stores the file in the root of the classpath (no "conf" item). 

Continuous Deployment with DEV@cloud Jenkins

If you want this done quickly with one click - launch the clickstart - see the button to the left ! Click it ! it will set up all of the below for you, but if you like to set things up by hand, read on:

Click on the Builds link in the toolbar to open your Jenkins instance, create a free style job and add your source repository.

For the job you need to add an "Execute script" build step, with the following command.

java -XX:MaxPermSize=256m -Xmx512M -jar /opt/sbt/sbt-launch-0.13.0.jar -Dsbt.log.noformat=true clean test dist

This will download the version of play you use, and run your tests.

CloudBees expects that logs will be printed to STDOUT it is a good idea to add the following to conf/logger.xml

<configuration>

 <conversionRule conversionWord="coloredLevel" converterClass="play.api.Logger$ColoredLevel" />

 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
   <encoder>
     <pattern>%date - [%level] - from %logger in %thread %n%message%n%xException%n</pattern>
   </encoder>
 </appender>

 <logger name="play" level="INFO" />
 <logger name="application" level="INFO" />

 <!-- Off these ones as they are annoying, and anyway we manage configuration ourself -->
 <logger name="com.avaje.ebean.config.PropertyMapLoader" level="OFF" />
 <logger name="com.avaje.ebeaninternal.server.core.XmlConfigLoader" level="OFF" />
 <logger name="com.avaje.ebeaninternal.server.lib.BackgroundThread" level="OFF" />

 <root level="ERROR">
   <appender-ref ref="STDOUT" />
 </root>
</configuration>

You can use Jenkins Cloudbees Deployer plugin to deploy continuously your play2 application. You'll the have to configure sbt build step to call the "dist" task, and setup the deployer with "first match" web application pattern set to dist/*.zip.

Play "dist" command and production mode

CloudBees supports "play dist" natively - this is the preferred production grade deployment recommended by the Play framework people. Some clouds, such as Heroku, naively run play in the development mode ('play run') - which is not recommended for production deployments. However, it is worth nothing that if you develop locally you may occasionally find a small change in behavior when running from a dist - you can try it out by unzipping the dist file locally, and running the start script in it for your platform.

Database Evolutions

Play supports database evolutions - when deploying to CloudBees, note that the app runs in production mode, to run migrations to the database, you will need to set a system property (or conf setting): 

bees config:set -a appid "applyEvolutions.default=true"

So the next time your application runs - it can run the evolution. This is NOT recommended however, it is better to run evolutions outside of a production deployment - perhaps in the Jenkins CI job, or from the desktop via the play command.

Connecting your app on the desktop to your CloudBees Database

If you are using a CloudBees provided database, you can connect from your desktop instance of the app (dev time) to your CloudBees database if you need to. 

Firstly run: 

bees db:info -p yourCloudBeesDbId

Then note the info and set the following environment variables: 

DATABASE_PASSWORD_DB="(from above)"

DATABASE_USERNAME_DB="(from above)"

DATABASE_URL_DB="mysql://(host and port from above)/(database username from above)"

You can then run play locally, via "play run" or "play start" - and you can run evolutions etc, as needed.

Play! version 1

If you are after version 1 support, see here

Created by Ivan Meredith on 2011/06/17 23:16