How to host a NodeJS website in AWS/GCP or any Linux server- Complete Guide.

Augustine Joseph
7 min readAug 20, 2023

--

This article is about hosting a website on a Linux server. Here an EC2 instance from AWS is used for demonstration.
Second Part: How to add a Domain name to a website and encrypt it using certbot.

Pre-hosting setup.

  1. Connect to a cloud database like MongoDB Atlas for NoSQL or ElephantSQL for PostgreSQL.
  2. Move all the keys and secrets to an .env file and add the .env and node_modules to .gitignore file.
  3. Push the host to GitHub.

Server Setup

  1. Create an account in AWS and start the free trial.
  2. In the dashboard, search for EC2 and select EC2 to create an instance of a Linux server using an Ubuntu image.

3. Click on the launch instance button to create a new instance. For a free instance select the following configurations.

4. Give any name to the instance. Choose a Ubuntu image, choose 20.04 LTS as it is more stable.

5. For instance type choose t3.micro or any instance which offers a free trial.

6. Click on the Create new key pair to generate a new key pair to ssh into the server using the computer.

7. In the create key pair, give any name and click on create key pair. The downloaded file will be used to connect to the AWS Ubuntu server instance we are creating. Keep the downloaded file safe and the file should not be modified.

8. In the firewall section, tick all boxes to allow traffic from both secured and regular HTTP connections.

9. Click on the Create instance button to create a new instance with the settings configured above.

In the instances list, we can see our instance running. Click on the instance name to access its settings.

Connecting to the server using SSH

This step is for Linux users Only:

Linux users have to run the following command to make the key read-only. Here key_pair is the name of the key. Open the terminal in the downloads folder (assuming this is where the key is downloaded) and run the following command.

chmod 400 key_pair.pem

For All OS users:

  1. Go to the instances dashboard by clicking on the instance name and click on the connect button.

Under the SSH Client, copy the highlighted link. This will be used to connect to the instance from the terminal.

Open the terminal in the download folder (assuming the previously downloaded .pem file is located in the downloads folder) and paste the copied link. Type yes to connect to the terminal.

Error!

If such an error is shown, do the first step mentioned in this section to make the key read only.

After successfully connecting, ubuntu@some_ip_address will be shown.
Now the connection to the server is successful
To reconnect to the server, open a terminal and paste the above copied link.

Setting up the server

Run the following commands to update the server.

sudo apt update && sudo apt upgrade -y

Install necessary packages and software.

sudo apt install -y nginx curl git

To install the latest NodeJS:

curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt install -y nodejs

To make sure Node is successfully installed, run:

node --version

Cloning the project from GitHub to Server

Copy the link to the repository from GitHub.

git clone <copied_link>
ls

The ls command shows the recently cloned repository.

Adding .env File to AWS instance.

The .env file is ignored in the git using .gitignore. So the cloned repository does not contain the file.

cd <repository_name>
sudo nano .env

Here, copy and paste the contents of the .env files from the local computer (VS Code).
After pasting the contents, press ctrl+O and Enter to write the changes. To exit nano press ctrl + X

Setting up PM2

Before configuring nginx and pm2, the code should be tested. To make sure the code runs without errors, run the following commands:

npm install
node index.js 
# replace index.js with actual filename.

Now the project will be running. If not, recheck for any missed steps and try again.
Press ctrl + C to exit and proceed to the next steps.

Now we need to run the project in the background at all times. For that we are using PM2 (Process Manager 2). PM2 can manage your application processes, ensuring they are running, restarting them in case of crashes, and allowing easy scaling of your application.
To install PM2 run the following command:

sudo npm install -g pm2@latest

To make sure PM2 is successfully installed, check its version:

pm2 --version

Start PM2

pm2 start index.js
# here index.js is the file. Use appropriate name based on your file name.

Start PM2 automatically on System reboots

pm2 startup systemd

Copy the command starting from the word ‘sudo’ to the end from the output of the above command. Paste it in the same terminal and press enter.

pm2 save

We have now created a systemd unit that runs pm2 for your user on boot.

sudo systemctl start pm2-ubuntu

# Here ubuntu is the user for the ubuntu os.
# The user can be found by running the command 'whoami'

If this error message is show, run the following command:

sudo reboot now

Now the connection to the server is lost and the server is rebooting. It might take a couple of minutes. Reconnect to the instance using the steps mentioned above.
After reconnecting go to the project’s folder using “cd <project_name>” command and run the command “ sudo systemctl start pm2-ubuntu ” again.

Now the command is executed successfully. Empty output shows success.

Check the status of the systemd unit:

sudo systemctl status pm2-ubuntu

# Here ubuntu is the user for the ubuntu os.
# The user can be found by running the command 'whoami'

Configuring Nginx as a reverse proxy server.

Nginx and Node.js are commonly paired in web applications. Node.js is the server-side runtime that processes your web application’s code and dynamic content. Nginx acts as a web server and reverse proxy in front of Node.js. It efficiently manages incoming web traffic, serves static files, and enhances security by filtering out malicious requests. This combination optimizes performance, scalability, and security for your web application, making it fast, reliable, and resilient, especially under high traffic loads.

To setup nginx run the following command in the terminal:

sudo nano /etc/nginx/sites-available/project_name

#replace project_name with your project name

Paste the following in the code and make sure the replace the port with the actual port used in your project and the server_name with the public_ipv4_address from the instance dashboard.

IP address Location in the Dashboard.
server {
listen 80;
server_name 16.xxx.xxx.233;

location / {
proxy_pass http://localhost:4000;
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;
}

}

Press ctrl + o to write the changes and ctrl + X to exit.

To link sites-available with sites-enabled:

sudo ln -s /etc/nginx/sites-available/your-site /etc/nginx/sites-enabled/
# Replace your-site with actual values.

To test if the configuration in Nginx is working correctly:

sudo nginx -t

If the output is similar to the above, proceed to the next step. Otherwise, review the steps and resolve the error.

To restart nginx:

sudo systemctl restart nginx

Now the website will be available at the public IP address. Make sure to use HTTP instead of HTTPS in the URL, since the connection is unencrypted and use port 80. The default behavior is using HTTPS.

Encrypting the connection and adding a Domain Name.

How to add a Domain name to a website and encrypt it using certbot.

--

--

Responses (1)