Hosting MERN app on AWS Ubuntu 22.04 - 2023

Stop wasting time searching how to host your project

Β·

10 min read

Hosting MERN app on AWS Ubuntu 22.04 - 2023

This article is for beginners' guide to hosting and deploying their projects to a server or any Ubuntu 22.04 machine. Here is the whole walk through of what is going to do in this article.


  • Creating AWS instance

  • Setup by installing library and application

    • Npm & Nodejs

    • MongoDB

    • Pm2 (npm package)

    • Nginx

    • UFW (firewall)

  • Starting serving

    • Running js using pm2
  • Securing server with SSL certificate


Preparations you need to take

Get a domain name for hosting.

Setting up your Linux server - Ubuntu 22.04 LTS

Whenever we get a server it's a good practice to update the repository and packages, If you are going to download and use new packages. In this case, we are using an apt package manager to install the necessary packages.

It's more like updating the whole system.

sudo apt update
sudo apt upgrade -y

If you are doing it for the first time this may take some time.

Installing software and required packages

For hosting a NodeJS app successfully we need some packages and dependencies.

  1. Installing NodeJS

So let's start by installing npm. Which also comes with NodeJS

sudo apt install npm -y

This will install npm with the latest version which is on the apt repository. But as of now, the day I am writing. This will be the download node of version 12. x.x. So this could be a problem if you try to use new features like a ternary operator or optional chaining Which is only supported on the latest versions of NodeJS.

To avoid any kind of problem with the NodeJS version and feature missing we need to update NodeJS and npm.

To update NodeJS we can use an npm package called n.

sudo npm install n -g
sudo n stable

This will update the NodeJS to the latest stable version. To check the node version use the following command

node --version
  1. Installing MongoDB

If you are using Atlas (a fully managed database cloud by MongoDB), You can skip this step. Otherwise, you need to install MongoDB locally to run your code.

You can refer to MongoDB's official installation doc for Ubuntu 22.04. By the time you read this article, the following commands may be outdated so I would recommend checking official installation documentation.

Anyway here is how we install MongoDB.

Install dependencies for the installation of MongoDB.

sudo apt install gnupg curl

Enter the following command to import the MongoDB public GPG Key from https://pgp.mongodb.com/server-6.0.asc

curl -fsSL https://pgp.mongodb.com/server-6.0.asc | \
   sudo gpg -o /usr/share/keyrings/mongodb-server-6.0.gpg \
   --dearmor

Create the /etc/apt/sources.list.d/mongodb-org-6.0.list file for Ubuntu 22.04 (Jammy) Other version's sources list is on Official documentation

echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-6.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list

Enter the following command to reload the local package database

sudo apt update

To install the latest stable version, use the following command

sudo apt install -y mongodb-org

The installation is complete. so let's enable Mongodb to start the startup of the system.

sudo systemctl enable mongod

To start MongoDB we can use

sudo systemctl start mongod

we can also view the status of the MongoDB service by simply typing sudo systemctl status mongod.

We successfully installed MongoDB and now we can access the MongoDB shell by typing mongosh.

  1. Installing PM2 (npm package)

PM2 is a process manager for Node.js applications that simplifies the process of managing and deploying Node.js applications in production environments. It is designed to keep your Node.js applications running continuously, ensuring high availability and improved performance. PM2 stands for "Production Process Manager 2."

PM2 is an npm package, and it's fairly easy to install.

sudo npm install pm2 -g

That's it PM2 is successfully installed globally.

  1. Installing Nginx

NGINX is an open-source web server software that can be used for web serving, reverse proxying, caching, load balancing, media streaming, and more. And it is really fast !.

NGINX is designed to handle a high number of connections simultaneously, making it one of the most powerful and scalable server software options on the market

To install nginx use the following command

sudo apt install nginx

This will install the latest stable version of Nginx available in the apt repository.

As our machine is a server and we don't need to manually start nginx as a service every time we boot or reboot our system. To address this issue we can enable nginx to run on start-up using the following command.

sudo systemctl enable nginx

To start nginx we can use

sudo systemctl start nginx

we can also view the status of the Nginx service by simply typing sudo systemctl status nginx.

  1. UFW (firewall)

UFW stands for "Uncomplicated Firewall." It is a user-friendly command-line tool used in Linux-based systems, such as Ubuntu, to manage the system's firewall settings. UFW provides a simple and easy-to-use interface for configuring and controlling firewall rules, making it accessible to both novice and experienced users.

NOTE: If you are using an AWS instance for hosting configuring UFW is not a necessary stop since AWS comes with its firewall called security groups. Learn more about it from their official documentation

To install UFW use -

sudo apt install ufw
πŸ’‘
To see available applications for adding in UFW use sudo ufw app list. you should see Nginx Full, Nginx HTTP and Nginx HTTPS is on the list.

now let's allow full HTTP and HTTPS access to nginx.

sudo ufw allow 'Nginx Full'

Use the following command to view all apps and ports managed by the firewall.

sudo ufw status
To                         Action      From
--                         ------      ----
Nginx Full                 ALLOW       Anywhere                  
OpenSSH                    ALLOW       Anywhere                  
Nginx Full (v6)            ALLOW       Anywhere (v6)             
OpenSSH (v6)               ALLOW       Anywhere (v6)

IMPORTANT NOTE: If you are using SSL to connect to an instance you must check OpenSSH is enabled in the firewall, to access your server. otherwise, you will have some real trouble accessing your server! , If OpenSSH is not listed in the sudo ufw status.

sudo ufw allow openssh

This will enable ssh to our server.

Start serving your app

Let's start by serving a simple express server.

  1. Create and open files in an editor.
cd ~
touch index.js
vim index.js
  1. wirte simple http sever in nodejs
const http = require('http');

const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
  1. Press escape and :wq to save and exit from Vim

Now we can start our server using PM2

pm2 start index.js --name test-server
# Your screen should looks like this
[PM2] Spawning PM2 daemon with pm2_home=/home/ubuntu/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/ubuntu/index.js in fork_mode (1 instance)
[PM2] Done.
β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ id β”‚ name           β”‚ namespace   β”‚ version β”‚ mode    β”‚ pid      β”‚ uptime β”‚ β†Ί    β”‚ status    β”‚ cpu      β”‚ mem      β”‚ user     β”‚ watching β”‚
β”œβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 0  β”‚ test-server    β”‚ default     β”‚ N/A     β”‚ fork    β”‚ 1152923  β”‚ 0s     β”‚ 0    β”‚ online    β”‚ 0%       β”‚ 37.3mb   β”‚ ubuntu   β”‚ disabled β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

That's it with the pm2 side. so let's configure Nginx for accessing this on the internet. Nginx default configuration is on /etc/nginx/sites-available so we are going to create a file with our domain name there.

sudo vim /etc/nginx/sites-available/your_domain_name

Replace your your_domain_name with your actual domain name. This will open an editor and we can add nginx configurations here.

server {
   server_name your_domain_name www.your_domain_name;
   location / {
       proxy_pass http://localhost:3000;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection 'upgrade';
       proxy_set_header Host $host;
       proxy_cache_bypass $http_upgrade;
   }
}

Now save and exit the file. To save and exit use escape and press :wqEnder. The next step is to add a soft link to this file we created to sites-enabled folder of nginx.

sudo ln -s /etc/nginx/sites-available/your_domain_name /etc/nginx/sites-enabled

It's a good practice to remove old non used nginx configs from sites-enabled folder

sudo rm /etc/nginx/sites-enabled/default

Test our newly added config.

sudo nginx -t
# Your screen should look like this
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Now let's restart nginx.

sudo systemctl restart nginx
πŸ’‘
use sudo systemctl status nginx to get the status of the nginx service.

Check your browser!

If everything is configured correctly so far, you should see "Hello world" in your browser by opening a new tab with your instance's public IP as your address.

You can just clone your project from Git Hub or edit index.js and run it in PM2 to customize the response.

If your project runs on a different you need to update the Nginx config to access the project from outside.

Adding SSL certificates - HTTP to HTTPS

After successfully hosting your project with Nginx now it's time to protect our website with an SSL certificate.

Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free TLS/SSL certificates, thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps. Currently, the entire process of obtaining and installing a certificate is fully automated on both Apache and Nginx.

This guide will walk you through the process of using Certbot to secure a free SSL certificate for Nginx on Ubuntu 20.04, and you'll also learn how to set it up for automatic renewal.

Let's install certbot along with its nginx plugin

sudo apt install certbot python3-certbot-nginx
  • Obtaining SSL certificate

Certbot needs to be able to find the correct server block in your Nginx configuration for it to be able to automatically configure SSL. Specifically, it does this by looking for a server_name directive that matches the domain you request a certificate for. In our case its your_domain_name.

sudo certbot --nginx -d your_domain_name -d www.your_domain_name

If that’s successful, certbot will ask how you’d like to configure your HTTPS settings.

OutputPlease choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Select your choice then hit ENTER. The configuration will be updated, and Nginx will reload to pick up the new settings. certbot will wrap up with a message telling you the process was successful and where your certificates are stored:

OutputIMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2020-08-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Your certificates are downloaded, installed, and loaded. Try reloading your website using https:// and notice your browser’s security indicator. It should indicate that the site is properly secured, usually with a lock icon. If you test your server using the SSL Labs Server Test, it will get an A grade.

With that being set you are good to handle hosting in Ubuntu 22.04.

πŸ’‘
This article is inspired by Digital Ocean's NodeJS hosting documentation. For further reference, you can always refer Digital Oceans doc.

Hope this article helps.

Stay creative; Thak you : 🀍

Β