Deploy a NodeJS app on EC2

aps08
7 min readApr 16, 2023

--

If you are trying to deploy a NodeJS application on EC2 using GitHub Actions, then this article is for you. In this article, I will be going through (1) Launching an EC2 instance, (2) Connecting to an EC2 instance (3) Adding a self hosted runner on github repository and (4) Running a NodeJS application on EC2 using CI/CD.

keywords — NodeJS, CI/CD, GitHub Actions, EC2, ubuntu, Instance, self-hosted, automation

Launching an EC2 instance

  1. Create an account on AWS and Login to the AWS console.
  2. Search EC2 on the search box and select the first option, which says EC2. Click launch instance button.
  3. You will be redirected to Launch an instance page, where you need to add some configuration. In the application and OS Image select ubuntu, and “ubuntu server 22.04 LTS” as shown in the below image. This server comes under AWS free tier.
AWS Ubuntu server selection

4. Under key pair, click create new pair. As I am going to connect using windows I will be selecting “.ppk”, which can be used with PuTTY to connect with EC2. Once you have selected the options and given a name to key pair, click create key pair, and a .ppk file will be downloaded in your machine.

5. Under network setting, select Allow SSH traffic from My IP/anywhere, and Allow HTTP traffic from the internet.

Select security options

6. Now click on launch instance, and your instance will be create in some time. Note that the instance state should be running in order to connect with it.

Connecting to an EC2 instance

  1. Go to the instance page, and see if your instance has running status as given in the below image.
instance running status

2. Click on the instance ID, which will redirect to your instance information page. Click on the connect option given on the top right corner. Select SSH, and it will show you steps to connect to the instance. Now copy the part highlighted in the image below, and save it for future.

Copy the highlighted part

3. Now open PuTTY and paste the copied part under the Host name section. And on the left side of the PuTTY panel click on SSH, and the Auth and select credentials. Under credentials browse and select the .ppk file which was downloaded in Launch an EC2 instance section step 4 for private key for authentication input.

Pasting host name and selecting credentials.

4. Click on open, and accept the prompt if any. If you receive a terminal, then you are connected to the EC2.

Adding a self hosted runner on github repository

  1. For this example, I have a sample NodeJS app, which just returns hello world and runs on localhsot:5000.
Sample NodeJS app

2. Under your project repository, click on settings, and select runners under the actions tab given on the left panel. Click on “New self-hosted runner”. And select Linux under the runner image. You will get list of command by github. You need to run these command one by one in order to connect this repository with the EC2 except the last command which says ./run.sh. Once you have run the command “./config.sh — url https://github.com/username/repository_name— token ALONGTOKEN” the EC2 server will show Authentication and prompt you for some value, you can keep everything as default and click enter to skips these steps.

note: all the content related to our project will be available to us inside _work folder.

Authentication successful in github

3. Now when you reload the github page, where you added the self-hosted runner. you will see a runner is added and showing status as offline.

Runner added on github

4. Since this instance is new, we don’t have NodeJS, npm and other important packages and tools to run a server on this. So you can copy and paste the command given below to update the instance and install all the required packages.

sudo apt update — updates the instance

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -” — downloads node resources

sudo apt-get install nodejs” — installs NodeJS

sudo npm i -g pm2” — pm2 is used to keep the NodeJS app running at the background.

sudo apt-get install nginx” — install nginx server

Now the basic setup on EC2 is complete. Let’s move to the next step.

Running a NodeJS application on EC2 using CI/CD.

  1. Now we add a github actions file in the code, so that we can setup a CI/CD pipeline for automated deployment. You the use the basic code given here.
GitHub Actions

The above configuration basically tell the server, to run the command given in the steps, every time there is a push on main branch using the self-hosted runner.

2. Currently our EC2 server is added to the repository but offline, to make is online or idle. Run the command below in order to change the state.

sudo ./svc.sh install

sudo ./svc.sh start

Now your runner will show idle status instead of offline.

Running showing idle status

3. Now we push one change into our github repository. The Github actions file will run and try to start the nodejs application and _work folder will be created in the server. This time it will FAIL as we are trying to restart a server which is not present. Now we will run the following command to run the server first.

cd _work/samplenodejsapp/samplenodejsapp/” — to go inside the project

pm2 start index.js — name=samplenodejs” — to start the server. (there are double hyphens before name). After running this command you will get a tabular status as given below.

pm2 job status

4. Now copy the Public IPv4 address of your instance and paste on a new tab. It will show nginx as given below, but why are we not getting the “hello world”. It is because we running this nodejs app on “localhost:5000” and the default HTTP port is 80, so we need to use redirect all our request with is coming at port 80 to localhost:500. In order to do this, we need to make changes into the nginx file. Type the command: “sudo nano /etc/nginx/sites-available/default” to open the nginx config file.

5. Once the file is open you will see, replace the part given in the first image given below, with the content given in the second image.

First image: delete this part
Second image: copy paste this part at the place

6. Now we need to restart the nginx server so that these changes can show results. Use command: ”sudo systemctl restart nginx” to restart the nginx server. Now we we go the instance IP on the new tab, we will see our app running.

Result

7. We can see the result, but we still need to verify if the CI/CD pipeline is working properly or not. Currently we only have 1 API, which says hello world. Let’s add a new API, which return something else. I have added the highlighted part into the code and push it to our project repository.

Highlighted part is added.

Now once the GitHub actions has run, we should have this API endpoint which returns a button. Now if we trigger /api2 on our instance IP we should see the result as given in below image.

API Endpoint is available

--

--