Using SSH client
If you want to use a SSH client then you will need to follow these steps;
- Open your preferred terminal
- cd into the folder where you stored the .pem key when creating your EC2 instance
- Run the following command, making sure to use the name of your pem key This is only required if you are using linux/mac you do not need to run this on windows
chmod 400 "<name of your pem key>.pem"
- Navigate to the EC2 Instances Dashboard
- Select a running EC2 instance
- On the top right of the screen there should be a Connect Button
- Copy the command highlighted in red and paste it to your terminal The terminal should be opened in the location of your pem key
- If there arent any errors you should be connected to your EC2 Instance via SSH
Setting Up Node.js
All of the next steps should be done inside the connected EC2 Instance
Once we are connected and our EC2 Instance the first step that we will need to do is to update the packages to the latest stable version, we can do this by running the following command
sudo apt update && sudo apt upgrade -y
After the packages have been installed we will need to install Node.js onto our Instance, the following command installs node 18 with npm. You can change the installed version by changing the “18.x” to your desired version
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
Verify the installation by running
node -v
npm -v
These command should yield the following output Note: It is not necessary that your version match the image below, what is important is these command should output a valid version
Create a simple Node.js Application
In the following section we will create a simple Node.Js application that we will run to test our routing
- Create a directory for your application
mkdir ~/testApp
cd ~/testApp
- Initialize the Node.js Project
npm init -y
- Create the Application
The following command will create a app.js file and open nano text editor inside your terminal
nano app.js
Paste the following content inside the nano editor
// app.js
const http = require('http');
const hostname = '127.0.0.1';
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}/`);
});
Save and exit nano by pressing ctrl + s ctrl + x
Using a process manager to run Node.js
In this section we will be using a process manager PM2 to run our node.js app that we have created.
The following command will install PM2 with npm:
npm install pm2 -g
check installation by running:
pm2 -v
It should output a version if the installation was successful
Next we will cd into the node app that we created earlier
cd ~/testApp
Normally we run node.js server with nodemon, which we can install by running:
npm i nodemon -g
After installing nodemon we can startup our node.js app by running the following command
pm2 start "nodemon app.js" --name "Test_App"
If all goes smoothly running the command
pm2 list
will display Test_App on the pm2 table
If we want to check the terminal logs of our PM2 application we can run the command
pm2 logs Test_App
Configuring Nginx as a Reverse Proxy
In this section we will use Nginx to route our node server that is running on port 3000 to our bare IP address.
- Installing Nginx
sudo apt install nginx -y
- Configure Nginx
cd into your nginx sites-available folder
cd /etc/nginx/sites-available
Here there should be a file called default, we will edit this file to route our port
sudo nano default
In the default file there should be a code block that will look something like such:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ /index.html;
}
}
We will change the “location / ” code block to route the base path i.e “/” to our node port
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;
}
Save and exit out of the editor and check if the nginx config is modified correctly by running the command
sudo nginx -t
It should output:
restart the nginx service:
sudo systemctl restart nginx
Testing the Setup
In this section we will test if our nginx routing was successful.
On your browser visit the static IP/elastic IP of your EC2 instance. It should be displaying “Hello World”
Conclusion
Congratulations! You’ve deployed a Node.js application on an EC2 instance with Nginx as a reverse proxy. This setup is production-ready, with Nginx handling HTTP requests and a system service ensuring your app’s uptime. From here, you might consider additional configurations, such as adding SSL with Let’s Encrypt, to further secure your application.