Deploying an Nodejs Express application to Elastic Beanstalk with PM2 | 2020

Chetan Bothra
2 min readOct 29, 2020

--

There are so many article that shows how to deploy an nodejs on beanstalk but most of them doesn’t works in 2020 and half of them don’t support expressjs. In this article I will explain you how you can deploy your nodejs express application to Elastic Beanstalk with pm2

Prerequisites

  • Already have a Node.js express application working locally
  • Knowledge on how to create Beanstalk application
  • An AWS account
  • Less than 15 min of your time

Step 1 : Launch a Beanstalk application. This is straight forward and I wouldn’t be spending much time on this.

Step 2 : Installing pm2 and and init with ecosystem

pm2 init

this will create Generate an ecosystem.config.jstemplate and replace accordingly

module.exports = {
apps: [
{
name: "name of your project",// <===== edit accordingly
append_env_to_name: true, // <===== add this line
script: "./bin/www.js", // path needs to be relative from ecosystem.config.js
env: {
NODE_ENV: 'development',
},
env_staging: {
NODE_ENV: 'staging',
},
env_production: {
NODE_ENV: 'production',
},

}
]
};

Step 3 : Update package.json for start script

{
"scripts": {
"start": "pm2 start ecosystem.config.js --env environment",
}

Step 4 : Create Procfile

For some reasons and i confirmed with AWS support that npm start doesn’t work out of box on ami linux 2 and so alternative was to use Procfile

web: npm start

NOTE: P is caps in Procfile

Step 5 : create ebextensions

We will be creating 2 files

File 1 : install_pm2.config to install pm2 globally

packages:
yum:
git: []

files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/03_npm_install.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)
cd $EB_APP_STAGING_DIR
npm install -g pm2

File 2 : renaming env name in package.json in step 3

Reason why I am doing this, In Step 3, We only can define npm start and not anything else. So how do we handle multiple envs

container_commands:
50_rename.config:
command: "/usr/local/bin/settings.sh"
files:
"/usr/local/bin/settings.sh":
mode: "000755"
content : |
#!/bin/bash
# Script to configure package.json file
# Fill variables from environment and parameter store
echo "Filling variables"
environment=$(aws --region $region ssm get-parameter --name "/$stack/$environment/envname" | jq -rc '.Parameter' | jq -rc '.Value')
if (/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir 2>1 ) ; then
app_staging_dir=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)
app_deploy_dir=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir)
else
app_staging_dir=$(/opt/elasticbeanstalk/bin/get-config platformconfig -k AppStagingDir)
app_deploy_dir=$(/opt/elasticbeanstalk/bin/get-config platformconfig -k AppDeployDir)
fi
conffile="/package.json"
echo "Filling $conffile with the correct values."
sed -i 's/environment/'$environment'/' $app_staging_dir$conffile

This will fetch env name from parameter store and replace this with env name you define.

That’s it ! deploy your code and we are good.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Chetan Bothra
Chetan Bothra

Written by Chetan Bothra

AWS Certified | GCP | DevOps | SRE | Docker | DevSecOps | Kubernetes | Automation | Terraform | Serverless | Blockchain

No responses yet

Write a response