Best way to deploy play2 app using Amazon Beanstalk
Asked Answered
P

7

11

I found fragmented instructions here and some other places about deploying Play2 app on amazon ec2. But did not find any neat way to deploy using Beanstalk.

Play is a nice framework and AWS beanstalk is one of the most popular services then why is there no official instruction to do this?

Has anyone found any better solution?

Ptolemaic answered 2/3, 2014 at 23:17 Comment(0)
T
14

Deploying a Play2 app on elastic beanstalk is now easy with Docker Containers in combination with sbt's experimental docker feature.

In build.sbt specify the exposed docker ports:

dockerExposedPorts in Docker := Seq(9000)

You should automate the following steps, but you can try this out manually to test that it works:

Generate a Dockerfile for the project by running the command: sbt docker:stage. Go to the ./target/docker/ directory. Create an elastic beanstalk Dockerrun.aws.json file with the following contents:

{
   "AWSEBDockerrunVersion": "1",
   "Ports": [
       {
           "ContainerPort": "9000"
       }
   ]
}

Zip up everything in that directory, let's say into a file called play2-test-docker.zip. The zip file should contain the files: Dockerfile, Dockerrun.aws.json, and files/* directory.

Go to aws beanstalk console and create a new application using the m3.medium or any instance type with enough memory for the jvm to run. Any instance with too little memory will result in a JVM error.

Select "Docker Container" in the Predefined Configuration dropdown.

In the application selection screen, select "Upload" and select the zip file you created earlier. Launch the app and then go brew some tea. This can take a very long time. Minutes. Subsequent deployments of the same app version should be slightly quicker.

Once the app is running and green in the aws console, click on the app's url and you should see the welcome screen of the application (or whatever your index file is).

Tetra answered 9/9, 2014 at 23:40 Comment(6)
I have followed all these steps but I receive a permission error when deplying, can you have a look please? #25821794Handle
Doublecheck your zip file to make sure all your files are there and that the path in the zip file is relative to the /target/docker directory. If you pass -v to unzip you should see a /bin directory. Or, if you unzip the file somewhere else, you should see Dockerfile and /bin in that directory. Finally, you should test deployment in docker locally by creating an image from the target/docker directory then deploying that image locally. If it starts on your machine, it will start on EBS; the beauty of docker.Tetra
I"m unable to edit my previous comment, the correct directory you should see in your zip file is files/, not bin. The relative path to the bin directory is files/opt/docker/bin/[project_name]Tetra
You also need to have an empty Volumes array, otherwise EBS will give you errors when you deploy new versions of your application, and return this error: #28213732Factitive
I created this little sample project to help people release on AWS Beanstalk. Hope it helps someone: github.com/Enalmada/play-beanstalkAntisepsis
See below: there's now a native Java SE options available.Landbert
M
12

Here's my solution that doesn't require any additional services/containers like Docker or Jenkins.

Create a dist folder in the root of your Play application's directory. Create a Procfile file containing the following contents and put it in the dist folder (EB requires port 5000):

web: ./bin/YOUR_APP_FILE_NAME -Dhttp.port=5000 -Dconfig.file=conf/application.conf

The YOUR_APP_FILE_NAME is the name of the executable in the bin directory, which is inside the .zip created by activator dist.

After running activator dist, you can just upload the created zip file into Elastic Beanstalk and it will automatically deploy the app. You also put whatever .ebextension folders and configuration files into the dist folder that you require for Elastic Beanstalk configuration. Ex. I have dist/.ebextensions/nginx/conf.d/proxy.conf for NGINX reverse proxy settings or dist/.ebextensions/env.config for environment variables.

Mala answered 31/3, 2016 at 2:56 Comment(4)
Also, I think the config file specification can be shortened to -Dconfig.resource=application.conf (assuming it is in the conf folder)Intellect
I've tried this as well but am getting a 502 Bad Gateway error when I go to the URL... Did you run into that? I can confirm that my app is running on port 5000 because my log aggregator is showing it. So I know the application is running and it is running on the correct port.Intellect
Any chance we could have a peak at the dist/.ebextensions/nginx/conf.d/proxy.conf file? I am running Play apps using the above method however I can't yet seem to get past getting the real IP address of the client. Yes I'm well aware of this: playframework.com/documentation/2.5.x/HTTPServer however it doesn't seem to solve the problem.Debtor
This worked like a charm for me. I had to tweak a couple of things tho: 1) The app needs a secret key as per play prod configuration, for testing purposes adding ` -Dplay.http.secret.key=somesecretkey` to the procfile or to application.conf should work. 2) application.conf has to have play.filters.hosts set to the host that EB generates in my case it was similar to ".myapp-env.mqcnjcf34yryt.us-east-2.elasticbeanstalk.com"Earp
L
10

Edit 2016: There's now a much better way to deploy your Playframework apps onto ElasticBeanstalk using the new Java SE containers.

Here's an article that walks you through deploying step by step using Jenkins to build and deploy your project: https://www.davemaple.com/articles/deploy-playframework-elastic-beanstalk-jenkins/


You can use custom AMIs that I keep updated here: https://github.com/davemaple/playframework-nginx-elastic-beanstalk

These run Nginx + Playframework and support standard zip files created using "activator dist".

Landbert answered 22/1, 2015 at 14:33 Comment(4)
This is definitely the way to go.Lawrenson
Thank you. I had been joking that, if only we had a virtual machine that would run packaged apps, we wouldn't need dockerInfrequency
Works for me. Thank you very much!Nancynandor
Any idea how to do this sbt style?Tarrah
I
2

We also saw this as being too much of a pain and have added native Play 2 support to Boxfuse to address this.

You can now simply do boxfuse run my-play-app-1.0.zip -env=prod and this will automatically:

  • create a minimal AMI tailor-made for your Play 2 app
  • create an elastic IP
  • create a security group with the correct permissions
  • launch an instance of your app

All future updates are performed as blue/green deployments with zero downtime.

This also works with Elastic Load Balancers and Auto-Scaling Groups and the Boxfuse free tier is designed to fit the AWS free tier.

You can read more about it here: https://boxfuse.com/blog/playframework-aws

Disclaimer: I'm the founder and CEO of Boxfuse

Isidore answered 17/11, 2015 at 11:25 Comment(1)
Thanks for the suggestion, it fixed my issues easily. Its nice to finally have a piece of software that does what it says it does and does it as easily as it says it does.Holdfast
E
1

I had some problems with other solutions found here and there. I guess that the problem is that I'm developing on Play 2.4.

Anyway, I could deploy the app to Beanstalk using Typesafe Activator and Docker:

  • In build.sbt I added this lines:
import com.typesafe.sbt.packager.docker.{ExecCmd, Cmd}

// [...]

dockerCommands := Seq(
  Cmd("FROM","java:openjdk-8-jre"),
  Cmd("MAINTAINER","myname"),
  Cmd("EXPOSE","9000"),
  Cmd("ADD","stage /"),
  Cmd("WORKDIR","/opt/docker"),
  Cmd("RUN","[\"chown\", \"-R\", \"daemon\", \".\"]"),
  Cmd("RUN","[\"chmod\", \"+x\", \"bin/myapp\"]"),
  Cmd("USER","daemon"),
  Cmd("ENTRYPOINT","[\"bin/myapp\", \"-J-Xms128m\", \"-J-Xmx512m\", \"-J-server\"]"),
  ExecCmd("CMD")
)
  • I went to the project's directory and ran this command in the terminal
$ ./activator clean docker:stage
  • I opened the [project]/target/dockerdirectory and created the file Dockerrun.aws.json. This was its content:
{
  "AWSEBDockerrunVersion": "1",
  "Ports": [
    {
      "ContainerPort": "9000"
    }
  ]
}
  • In the same target/docker directory, I tested the result, built, checked and ran the image:
$ docker build -t myapp .
$ docker images
$ docker run -p 9000:9000 myapp
  • As everything was ok, I zipped the content:
$ zip -r myapp.zip *

My zip file had Dockerfile, Dockerrun.aws.json and stage/* files

  • Finally, I created a new Beanstalk app and uploaded the zip created on the last step. I took care of select "Generic Docker" on "Predefined configuration", when I was creating the app.
Ellieellinger answered 7/1, 2016 at 3:27 Comment(4)
how does this process deal with app secrets (like db passwords, etc)? Does it expect secrets to be hardcoded in application.conf?Taps
@Taps Hardcode? No, that will be worst. App secrets should be loaded from environment variables. Tbh, I don't remember if you can do that with Beanstalk. The last time I used that technology was two years ago.Ellieellinger
Afaik, EB allows setting env variables but app inside of the docker container has no access to them. Since I don't want to hardcode secrets into the docker image and there seems to be no way to get env variables from EB, no docker for now :\Taps
@Taps Maybe this helps ==> #25150268Ellieellinger
K
0

Beanstalk only supports WAR deployment and Play doesn't officially support WAR deployment. If you want to use EC2 then you should instead just create an EC2 instance and follow the deployment instructions: http://www.playframework.com/documentation/2.2.x/ProductionDist

Kalevala answered 3/3, 2014 at 0:3 Comment(0)
B
0

Deploying play 2.* apps in aws ec2 is very diffrent until you have found this much better way to do it. I mean ansible is promising a great solution to that. though it is still needed to work with new setup of ansible, and its playbook but that must be worthy. I have found these reads very recently and yet to apply them in my project. I hope following reads will help you to learn more:

Ansible + play + aws ec2

Read it to know more about Ansible to deply play in aws

Thanks! Hope this will help you to kick your start. Please do share more knowledge you gain during the procedure or if there is any simple way to solve this complicated deployment problem.

Biffin answered 5/7, 2014 at 12:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.