Hosting MERN app on AWS Ubuntu 22.04 - 2023
Stop wasting time searching how to host your project
Table of contents
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.
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
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
.
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.
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
.
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
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.
- Create and open files in an editor.
cd ~
touch index.js
vim index.js
- 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}/`);
});
- 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
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.
Digital Ocean's
NodeJS hosting documentation. For further reference, you can always refer Digital Oceans doc.Hope this article helps.
Stay creative; Thak you : π€