Deploying Code on GitHub and EC2 Using AWS CodeDeploy (2)
May 01, 2021
This is the second writing about deploying a Node.js app using CI/CD tools, AWS CodeDeploy and AWS CodePipeline. The first article focuses on creating an EC2 instance and deploying a Node.js app in the instance using GitHub, CodeDeploy and CodePipeline. The below is about how to update codes and deploy them.
Table of Contents
- Updating appspec.yml
npm
andpm2
Not Found- Final Comment
Updating appspec.yml
In the previous article, I used the following appspec.yml
to upload my files to my EC2 instance:
version: 0.0
os: linux
files:
- source: ./index.js
destination: /home/ubuntu/your-app-name
- source: ./package.json
destination: /home/ubuntu/your-app-name
permissions:
- object: /home/ubuntu
owner: ubuntu
group: ubuntu
type:
- directory
- file
For my node.js app, I use npm
and pm2
. To automate the entire deployment process (e.g, npm install
and pm2 reload all
), we can use hooks of CodeDeploy. The npm install
and pm2 reload install
can be run during the AfterInstall
lifecycle. The updated appspec.yml
would be:
version: 0.0
os: linux
files:
- source: ./index.js
destination: /home/ubuntu/your-app-name
- source: ./package.json
destination: /home/ubuntu/your-app-name
hooks:
AfterInstall:
- location: scripts/AfterInstall.sh
timeout: 1000
permissions:
- object: /home/ubuntu
owner: ubuntu
group: ubuntu
type:
- directory
- file
In scripts
directory, create and save AfterInstall.sh
:
#!/bin/bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
export HOME="/home/ubuntu/"
sudo PM2_HOME=/home/ubuntu/.pm2 pm2 list
cd /home/ubuntu/api
npm install
pm2 start /home/ubuntu/api/ecosystem.config.js
npm and pm2 Not Found
In AfterInstall.sh
, if only the last three lines are included, it will not be working because it cannot find npm
and pm2
. The npm
issue can be solved by adding the following three lines:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads
The above does not solve an issue related to pm2
. For example, when you read the logs on CodeDeploy, your build would fail, and you are likely to see the following messages:
[PM2][Initialization] Environment variable HOME (Linux) or HOMEPATH (Windows) are not set!
[PM2][Initialization] Defaulting to /etc/.pm2
It is because "pm2
needs to know your HOME path." By adding export HOME="/home/ubuntu/"
in the AfterInstall.sh
, that problem is solved.
Final Comment
In my case, none of the processes appeared in the pm2
table (using sudo pm2 status
) even though I followed the instructions. It was because my app was launched at a different PM2_HOME
location. By entering and saving sudo PM2_HOME=/home/ubuntu/.pm2 pm2 list
in my `AfterInstall.sh, the process would appear in the status table.