Migrating Play2 (and other) apps to AWS Beanstalk (via Docker)

As you would have heard by now - the RUN@cloud service is winding down.

Thus, we have been working to help users migrate to one of the many services out there that can host their app.

In this blog I want to cover a bit about Play2 apps - as they are some of our most popular. A lot of this can apply to ANY type of app. Beanstalk now supports docker based deployment - this is super convenient - as you can be sure that your app runs locally, on your desktop, just like you would have with play2 normally, before you try to run it on beanstalk.

For an app to run on beanstalk via docker - basically you need a zip file with a Dockerfile in the root (there are other options, but lets narrow it). This can work for, well any type of app.

In fact I made a sample app here - the thing you deploy is the app directory (you cd into the app dir - and zip it up - Dockerfile must be at the root) - just to give you an idea of how simple the docker feature is on beanstalk (of course - always run “docker build -t testapp .” locally - and run it - to ensure it runs! Don’t leave it for Beanstalk to debug it - as the turn around time for debugging Dockerfile issues will be annoyingly slow - do it on your desktop - that is what docker shines at).

For Play2 - things are possibly even simpler. Since Play 2.3 - a “native” deployer has been included - which can produce the app, with dependencies, with a functional Dockerfile - which works find out of the box on beanstalk.

The sample app is here. This is a vanilla play2 stub application - just a starting point - with one change - to build config:

Add these imports and changes to build.sbt:

import NativePackagerKeys._
import com.typesafe.sbt.SbtNativePackager._

And then docker config:

maintainer in Docker := “John Smith @example.com>
dockerExposedPorts in Docker := Seq(9000)

This allows sbt (play build tool) to generate a correct Dockerfile. The exposed port will be used by beanstalk to direct traffic to the app.

Once you have this, you can run:

activator docker:stage

This will produce a target/docker directory. Change into that directory - and run:

docker build -t myapp . 
docker run -p 9000:9000 myapp

This will ensure that you can fire up your play app locally in docker - you don’t have to do this last step every time - but if you are unsure the deployment package is correct, then this will confirm it works. If it works here - it should work the same in beanstalk.

The contents of that target/docker directory - zipped up - are what you can deploy to beanstalk (it will build the docker image for you as part of the autoscale group setup - as you deploy). Instructions on how to zip up are here.

It can be that easy - obviously if you have a DB, and variables need to be injected, you will need to do that in the “beanstalk” way (via environment variables - which can be referred to via the play conf file).

Deploying from DEV@cloud

Jenkins on DEV@cloud comes with a beanstalk deployer, and this works just fine with Docker based apps, and play2 docker apps. With Play2 - you can run your test and build as normal - the only thing you need to change is to add the docker:stage step above - and then zip up the directory, and tell the deployer plugin where the zip file is. 
An example build step is covered here.
Beanstalk apps require that you set them up before you automate the deployment via the plugin (note that if you want, you can also use the aws command line from Jenkins - which places no limits on what you can automate).
The configuration for the app will look something like this: 
For this to work - you should have created a Beanstalk app from the Beanstalk web GUI first - you can try a direct manual deployment for the first time using a zip file if you like. 
Next - setup an S3 bucket (as named above) - that is where versions of the app built on DEV@cloud will be stored. 
Then set the Application Name you setup in the web GUI, put a version label (you can use any Jenkins project variable here, such as build number). 
The Environment Name is also what you setup before - normally it follows “appname-env” convention - but doesn’t have to - but it has to exist in Beanstalk. 
Finally - point to the zip file that was created in the build step (this is the zip file that has the Dockerfile at the root). 
The first deploys can take a few minutes - but generally they speed up. 
Read here for how to setup the beanstalk deployer.
And here is our general migration guide.


Blog Categories: 


Is this still valid? I have been trying variations on this for two days without finding the right combination. Thank you for this post and any thoughts you have to offer.

This may be a bit out of date (well over a year old, and beanstalk has changed some). What specific errors were you seeing?

There's now first class support for Playframework apps on Elastic Beanstalk using the new Java SE container types. Here's an article that walks you through preparing your app for deployment using a standard ```activator dist``` command: https://www.davemaple.com/articles/deploy-playframework-elastic-beanstalk-jenkins/

Add new comment