Deploying NestJS API on AWS EC2 & RDS using ubuntu server and PM2

Verdotte Aututu
6 min readSep 2, 2022

--

The application deployment process known as DevOps has drastically involved in the modern area of software engineering and knowing how to set up the deployment process can significantly improve and automate the shipment of various application features to the users. There are obviously a lot of app deployment services like GCP, Heroku, AWS, and Digital Ocean. As mentioned in the title, we will be using AWS as far as this article is concerned.

In order to make the most of this tutorial, sign up for an AWS free tier account using this link.

Tools & Stacks

NestJS

A progressive Node.js framework for building efficient, reliable and scalable server-side applications. Given the scope of this article is mainly deployment, we shall not cover the API implementation but cloning the repository that contains a CRUD API using the Postgres database.

AWS EC2

An Ubuntu 20.04 LTS Amazon Elastic Compute Cloud (Amazon EC2) instance will be used to deploy the NestJS API. We will install multiple packages in this instance in order to run our app smoothly.

AWS RDS

We shall create a Postgres database instance to store all the information of our small NestJS API.

PM2

PM2 is a daemon process manager that will help us manage and keep our application online once deployed.

Creating an Ubuntu server EC2 instance on AWS

Login to your AWS account, search for AWS EC2 from your console and click launch instance. Select the Ubuntu server and click next.

After selecting the Ubuntu server 22.04 LTS, proceed with the free selected tier.

Proceed with the next given we want to keep the default configuration.

Make sure you add the following security rules that will help us to log in to our server using SSH and access the 3000 port that we shall set for the API.

Right before launching our instance, let us create and download our instance key pair. Once downloaded, move it under the ~/.ssh directory.

At this point, we have successfully launched our EC2 server. In order to connect locally to our current EC2 instance, select it and click connect.

Open your terminal and run the following command:

chmod 400 <YOUR KEY PAIR PATH>chmod 400 ~/.ssh/my-ec2-rsa.pem

After that, run the next command to get connected to the server locally.

ssh -i "<YOUR KEY PAIR PATH>" <YOUR EC2 INSTANCE PUBLIC IPv4 DNS>ssh -i "~/.ssh/my-ec2-rsa.pem" ubuntu@ec2-54-87-3-233.compute-1.amazonaws.com

Click yes to confirm the connection.

Dependency installation & project cloning

In order to get started with our server, we are going to install a couple of dependencies. Run the following command to update existing dependencies and install nodeJS, git & npm:

sudo apt-get install nodejs git npm

Once the above packages are installed, we can easily install yarn & pm2 by running this command:

sudo npm install yarn pm2 -g

Given the main scope of this tutorial is deployment, we won’t spend time implementing the project here, but we are going to clone the project from this repository.

git clone https://github.com/verdotte/nest-crud-api.gitcd nest-crud-apiyarn install

Creating a Postgres database instance on AWS RDS

Navigate to the AWS console, select the RDS service and create a database

We are going to use the free tier as far as this tutorial is concerned.

Add database setting configurations

While selecting the VPC and subnet, make sure it’s the same as the ones of your EC2 instance created above and public access must be set to no.

Add the database name, by default 5432 will be set as the port number.

Our database instance is now launched and running, the next thing is to make sure our database can communicate with our EC2 instance. In order to do that, edit the security rules of the created database instance and add these rules under inbound rules:

Add PM2 and Database configuration

Open the cloned project on your text editor, create a file under the root directory named app.json and add the following content:

Basically, PM2 will be using the above file for starting, stopping and destroying the app.

In order to find your database credentials, click on your database instance on AWS RDS and select Connectivity & Security menu.

Let us create the .env file which will store all the database credentials. Make sure the .env file is created under the project root directory.

You can also add the following commands related to PM2 under the scripts section of your package.json.

Test the API

All the configurations are set up, we are going to execute a couple of commands in order to get our API running on the server.

sudo yarn build && yarn start

The above command will build and start the app and should get the following output if everything goes well:

We can open another terminal to run our database migrations using this command:

yarn migrate:run

Everything seems to work as expected at this point, however, there’s a problem while trying to access the API after closing the terminal where the app is running. PM2 will help us to solve that by running the app through the commands added above for starting, stopping and destroying the app using PM2.

Let us build and start the app using PM2

sudo yarn pm2:deploy:app

From here, you can head over to the API documentation endpoint: http://ec2-54-87-3-233.compute-1.amazonaws.com:3000/v1/doc-api and test other endpoints.

Conclusion

We can literally conclude deploying an app on an AWS EC2 instance required multiple steps and skills, ranging from knowing how to play around with the AWS platform (launching an instance, editing security rules, etc…) to connecting your local computer using SSH.

In this tutorial, we manage to explain the necessary steps in order to deploy the app AWS EC2, but there is other stuff we didn’t cover such as setting up CI/CD to automate the deployment process, allowing requests through HTTPS, connecting with a domain, etc…, however, this work through is enough to get one started.

--

--

Verdotte Aututu
Verdotte Aututu

Written by Verdotte Aututu

Software Engineer | Backend | Blockchain | DAPP | Web3 | NodeJS | AWS

Responses (3)