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

Written by: Michael Neale

5 min read

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"
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 S3bucket (as named above) - that is where versions of the app built on DEV@cloudwill 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 Dockerfileat the root).

The first deploys can take a few minutes - but generally they speed up.

Read here for how to setup the beanstalk deployer.

Read more about elastic beanstalk and docker from Amazon .

And here is our general migration guide .

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.