Setup NodeJS application server on AWS EC2 + Ubuntu + Nginx
Probably! You are here to know the first step towards hosting Nodejs application server on Amazon EC2 instance. Let me share what steps I would follow to do this job again.
I am assuming here that you have a running EC2 instance of linux (for me its Ubuntu 22.04) and you are able to connect via ssh.
In this tutorial we will install NodeJs and run this server and then we will learn what is the need of reverse proxy server(Nginx or Apache) with it.
Creating a NodeJs application Server
connect to your instance via terminal/putty
ssh -i <path/privateKey.pem> <username>@<public ip address>
Install NodeJs
Downloading node source file$ cd ~
$ curl -sL https://deb.nodesource.com/setup_14.x -0 nodesource_setup.sh$ sudo bash nodesource_setup.sh
sudo apt install nodejs
In order for some npm
packages to work (like compiling code) you will need to install the build-essential
package:sudo apt install build-essential
Build a NodeJs Application
nano hello.js
usually i create this directory at cd /var/www/<project-name>
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}/`);
});
Run the server node hello.js
outputServer running at http://localhost:3000/
Install Nodejs process manager to keep application running 24/7
sudo npm install pm2@latest -g
pm2 start hello.js
Output...
[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────────────┬────────────────┬──────────┬───────────
│ id │ name │ mode │ ↺ │ status │ cpu │ memory
├────┼────────────────────┼────────────────┼──────────┼──────────
│ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb
└────┴────────────────────┴───────────────────────────────────────
What if application crashes or killed ? here we need to relaunch our application on system startup using startup
command
pm2 startup systemd
due to this pm2 will relaunch and its managed process will start.
output will include a command to run with superuser privileges in order to set PM2 to start on boot
Output[PM2] Init System found: systemd
<user-name>
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u <user-name> --hp /home/<user-name>
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u <user-name> --hp /home/<user-name>
save the PM2 process list and corresponding environmentspm2 save
start the service with systemctl
for me username is root
sudo systemctl start pm2-root
Setting Up Nginx as a Reverse Proxy Server
so far your application is running on localhost of your instance, but you need to setup a way to access it from the internet. We will set up the Nginx web server as a reverse proxy for this purpose.
sudo apt install nginx
Adjusting the firewall
sudo ufw allow 'Nginx HTTP'
now check on browser that default Nginx HTML page is showing
Now, if Nginx wants to access the project file it should have the necessary permission.
To ensure that your permissions are correct and allow the owner to read, write, and execute the files while granting only read and execute permissions to groups and others, you can input the following command
sudo chmod -R 755 <path of project directory>
in Linux chmod is a build-in command that manages the access permissions. It can assign groups, users, and others to have permission for executing, reading, and writing permission on a certain file or directory.
755 assigns read, write and execute permission to a user or group.
Configuring Nginx
Nginx has default HTML page on port 80, here we need to unlink the default page and connect to the Nodejs application
sudo unlink /etc/nginx/sites-available/default
sudo rm /etc/nginx/site-enabled/default
remove the default file in case of error on sudo nginx -t
create new config file for our project
sudo nano /etc/nginx/sites-available/myserver.conf
#The Nginx server instance
server{
listen 80;
server_name wach.quest;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# location /overview {
# proxy_pass http://127.0.0.1:3000$request_uri;
# proxy_redirect off;
# }
}
}
For the next step, let’s enable the above file by creating a symbolic from it to the sites-enabled
directory, which Nginx reads from during startup
sudo ln -s /etc/nginx/sites-available/myserver.conf /etc/nginx/sites-enabled/
The server block is now enabled and configured to return responses to requests based on the listen
port and location
path.
sudo nginx -t
to test nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Once Nginx test is successful, we need to restart Nginx
sudo systemctl restart nginx
Now we are expecting our server response on the browser, let’s see
Congratulations! your NodeJs application is up and running on default port 80.
Final step: Go drink some water 🥛