Skip to content

Deploying a NodeJS app to Elastic Beanstalk

Philip Callender edited this page Jul 17, 2016 · 13 revisions

The instructions here assume the Elastic Beanstalk environment for your application is already set up. To set up a new environment see Setting up Elastic Beanstalk.

Before doing anything here it is probably best to have a look around the Amazon Elastic Beanstalk Dashboard, which is probably somewhere like https://ap-southeast-1.console.aws.amazon.com/elasticbeanstalk/home?region=ap-southeast-1.

2016-07-17_01-00-45

In particular, become familiar with the concepts

  • you can have multiple applications.
  • each application can have multiple environments.
  • Environment names must be unique across all your applications.
  • The name used in the Environment Url (e.g. http://mhp-test.ap-southeast-1.elasticbeanstalk.com) will be unique across all EB users in your region.
  • Application versions are uploaded versions of the application, and can be deployed on any environment.

Preparing your Application

A few files need to be added to tell EB how to deploy your application.

  1. Check you have an up to date package.json.

  2. Create .elasticbeanstalk/config.yml (update the application and environment names to those in the dashboard):

     branch-defaults:
       default:
         environment: mhp-test
         group_suffix: null
       master:
         environment: mhp-test
     global:
       application_name: mHealthPharma-api
       default_ec2_keyname: phil-singapore
       default_platform: Node.js
       default_region: ap-southeast-1
       profile: null
       sc: null
    
  3. If your application has healthcheck URL other than just /, add a file named .ebextensions/healthcheckurl.config:

     option_settings:
       - namespace:  aws:elasticbeanstalk:application
         option_name:  Application Healthcheck URL
         value:  /echo/stuff
    
  4. Elastic Beanstalk uses a reverse proxy named nginx to map port 80 externally to port 3000 (or other) on your NodeJS server. Sometime it does not get the mapping right (this seems to be the case if your application opens multiple ports). If you have that problem, see my answer to this StackOverflow question - the documentation provided by both Amazon and a Google search is misleading.

Uploading your Application to Elastic Beanstalk

There are two ways to upload the application to your EB environment.

  • Zip the contents of your project and upload it from the Elastic Beanstalk Dashboard.
  • Upload the project using the AWS CLI (command line interface).

Uploading via a Zip file

There's a bunch of files EB doesn't need, that will just bloat your zip file (e.g. you don't need the Git files, the test cases, or the files in node_modules). Without these files your uploads will be much faster.

On OSX the easiest way to create a zip file is to right click on the folder in Finder and select "Compress ..." however this puts everything in the zip file, and also create OSX-specific meta-data that prevent Elastic Cache from deploying your project.

The best approach is to use a script to create the zip file. For example this zip-for-elastic-beanstalk.sh will place a sequentially numbered zip file in the Desktop directory:

#!/bin/bash
#
#	This command will zip up the contents of this project, and place the zip file on the Desktop
#
LOCATION=~/Desktop
PROJECT=mHealthPharma-api

# Find the next version number
cnt=1
while true ; do
	filename=${LOCATION}/${PROJECT}-${cnt}.zip
	[ ! -r ${filename} ] && break;
	cnt=`expr $cnt + 1`
done
echo Creating file ${filename}

# Now zip up the file
zip -r -X ${filename} \
	.ebextensions/ \
	.elasticbeanstalk/ \
	_certs \
	app.js \
	package.json \
	public/ \
	routes/ \
	views/
status=$?

# Exit with the same status as the zip command
exit $status

Run this script is as easy as:

$ ./zip-for-elastic-beanstalk.sh 
Creating file /Users/philipcallender/Desktop/mHealthPharma-api-19.zip
  adding: .ebextensions/ (stored 0%)
  adding: .ebextensions/healthcheckurl.config (deflated 22%)
  adding: .elasticbeanstalk/ (stored 0%)
  adding: .elasticbeanstalk/config.yml (deflated 40%)
  adding: app.js (deflated 63%)
  adding: package.json (deflated 45%)
  adding: public/ (stored 0%)
  adding: public/images/ (stored 0%)
  ...
  adding: views/layout.jade (deflated 26%)

Once you have the zip file you can upload it to replace the running version of an application.

2016-07-17_01-24-18

Once the Application has been upgraded you can jump directly to it's webpage by clicking on the URL shown on the dashboard.

2016-07-17_01-27-34

Uploading with the AWS ClI

To install the Command Line Interface on your machine see Installing the AWS CLI.

When the application/environment was created on Elastic Beanstalk, it should have been defined to us a "key pair", and the person creating that key pair would have downloaded a credentials file with a name such as mHealthPharma.pem. Before using the CLI to deploy you will need to do two things:

  1. Check this key pair name is being used in .elasticbeanstalk/config.yml with a line like:

     default_ec2_keyname: mHealthPharma
    
  2. Get a copy of the credentials file and place it in ~/.ssh and set it's permissions:

     $ chmod 600 ~/.ssh/mHealthPharma.pem
    

With that in place you can simply run:

$ eb deploy
Creating application version archive "app-0088-160717_223708".
Uploading mHealthPharma-api/app-0088-160717_223708.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.                               
INFO: Deploying new version to instance(s).                         
 -- Events -- (safe to Ctrl+C) Use "eb abort" to cancel the command.

It will take a while to run, and you can follow the upload progress on the Elastic Beanstalk Dashboard.

Debugging Problems

When a problem occurs you will usually only see limited information in the dashboard's Recent Events section. To see the log output of your NodeJS application, click on the Logs tab.

2016-07-17_01-28-32

Try Request Logs->Last 100 Lines first - in most cases it will contain what you need to see.

Keep in mind that there are two different types of errors:

  1. The load balancer or it's Health Check configuration are incorrect, or
  2. Your application is not working.

Clarifying the type of error first will save a lot of time.

Other Topics

Installing the AWS CLI

From http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html#eb-cli3-install-osx:

$ brew install awsebcli

Creating a zip file

Before deploying you need to create a zip file. Unfortunately the default zip operations on OSX place extra metadata files into the .zip file, and these cause problems for Elastic Beanstalk. To prevent this, use the following command to bundle your application (run in the project directory):

zip -r -X ~/Deskytop/myapp-2.zip .

Hard-core Debugging

If looking at the logs as described above does not let you solve your problem, you might need to log onto the actual EC2 Instance being used by Elastic Beanstalk. Here are the steps:

  1. You will need the same credentials installed as used for the CLI deployment (e.g. ~/.ssh/mHealthPharma.pem). Don't forget to run chmod 600 ~/.ssh/mHealthPharma.pem.

  2. On the EC2 Dashboard click on Instances, then select the instance with the same name as you EB environment. Confirm the _Key pair name` is the same, and take note of the IP address.

  3. You should be able to log on to the EC2 instance using this command (replace the permissions file and the IP address):

     $ ssh -i ~/.ssh/mHealthPharma.pem ec2-user@52.76.116.188
    

2016-07-17_22-53-37

References

http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3.html

Clone this wiki locally