Install and Configure Node.js with Nginx on Ubuntu 20.04

Node.js is an opensource a JavaScript runtime environment which can be developed to build a server-side and network application. Linux, Mac OS X, FreeBSD, and Windows are all supported. Though Node.js can be run on the command line, we’ll focus on it running as a service through this tutorial. In this way, they will restart on a reboot or failure and can be used in a production environment.

We will setup production-ready Node.js environment on Ubuntu 20.04 server. We will use PM2 to managed and run a Node.js application, and provide users access to the application through an Nginx web server reverse proxy directive.

Initial Setup

Start by updating the packages to the latest version available.

sudo apt update
sudo apt upgrade

Install Specific Node.js version

You can install specific Node.js version from the Node.js repositories.

$ curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -

## Installing the NodeSource Node.js 14.x repo...

## Populating apt-get cache...

+ apt-get update
Hit:1 http://us-east-2.ec2.archive.ubuntu.com/ubuntu focal InRelease
Hit:2 http://us-east-2.ec2.archive.ubuntu.com/ubuntu focal-updates InRelease
Hit:3 http://us-east-2.ec2.archive.ubuntu.com/ubuntu focal-backports InRelease
Hit:5 http://security.ubuntu.com/ubuntu focal-security InRelease
Hit:4 https://packages.cloud.google.com/apt kubernetes-xenial InRelease
Reading package lists... Done

## Confirming "focal" is supported...

+ curl -sLf -o /dev/null 'https://deb.nodesource.com/node_14.x/dists/focal/Release'

## Adding the NodeSource signing key to your keyring...

+ curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor | tee /usr/share/keyrings/nodesource.gpg >/dev/null

## Creating apt sources list file for the NodeSource Node.js 14.x repo...

+ echo 'deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_14.x focal main' > /etc/apt/sources.list.d/nodesource.list
+ echo 'deb-src [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_14.x focal main' >> /etc/apt/sources.list.d/nodesource.list

## Running `apt-get update` for you...

+ apt-get update
Hit:1 http://us-east-2.ec2.archive.ubuntu.com/ubuntu focal InRelease
Hit:2 http://us-east-2.ec2.archive.ubuntu.com/ubuntu focal-updates InRelease
Hit:3 http://us-east-2.ec2.archive.ubuntu.com/ubuntu focal-backports InRelease
Hit:4 http://security.ubuntu.com/ubuntu focal-security InRelease
Get:5 https://deb.nodesource.com/node_14.x focal InRelease [4583 B]
Hit:6 https://packages.cloud.google.com/apt kubernetes-xenial InRelease
Get:7 https://deb.nodesource.com/node_14.x focal/main amd64 Packages [775 B]
Fetched 5358 B in 1s (10.3 kB/s)
Reading package lists... Done

## Run `sudo apt-get install -y nodejs` to install Node.js 14.x and npm
## You may also need development tools to build native addons:
     sudo apt-get install gcc g++ make
## To install the Yarn package manager, run:
     curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null
     echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
     sudo apt-get update && sudo apt-get install yarn

Now install the NodeJS app with specific version.

$ sudo apt install nodejs
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  nodejs
0 upgraded, 1 newly installed, 0 to remove and 46 not upgraded.
Need to get 25.4 MB of archives.
After this operation, 123 MB of additional disk space will be used.
Get:1 https://deb.nodesource.com/node_14.x focal/main amd64 nodejs amd64 14.19.1-deb-1nodesource1 [25.4 MB]
Fetched 25.4 MB in 1s (46.5 MB/s)
Selecting previously unselected package nodejs.
(Reading database ... 149395 files and directories currently installed.)
Preparing to unpack .../nodejs_14.19.1-deb-1nodesource1_amd64.deb ...
Unpacking nodejs (14.19.1-deb-1nodesource1) ...
Setting up nodejs (14.19.1-deb-1nodesource1) ...
Processing triggers for man-db (2.9.1-1) ...

Verify Services

$ node -v
v14.19.1

$ npm -v
6.14.16

$ sudo apt install build-essential

Creating a Node.js Application

$ vim 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');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Run and verify NodeJS app with the following command.

$ node app.js
Server running at http://localhost:3000/

$ curl http://localhost:3000
Hello World!

Installing PM2

Next let’s install PM2, a process manager for Node.js applications. PM2 makes it possible to daemonize applications so that they will run in the background as a service.
Use npm to install the latest version of PM2 on your server:

$ sudo npm install pm2@latest -g
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
/usr/bin/pm2 -> /usr/lib/node_modules/pm2/bin/pm2
/usr/bin/pm2-dev -> /usr/lib/node_modules/pm2/bin/pm2-dev
/usr/bin/pm2-docker -> /usr/lib/node_modules/pm2/bin/pm2-docker
/usr/bin/pm2-runtime -> /usr/lib/node_modules/pm2/bin/pm2-runtime
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.2 (node_modules/pm2/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ pm2@5.2.0
added 182 packages from 182 contributors in 10.129s

Now start the app.js application with PM2.
​  
$ pm2 start app.js

[PM2] Starting /home/ubuntu/app.js in fork_mode (1 instance)
[PM2] Done.
┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id  │ name   │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0   │ app    │ default     │ N/A     │ fork    │ 3234934  │ 0s     │ 0    │ online    │ 0%       │ 26.0mb   │ ubuntu   │ disabled │
└─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

Verify Node JS Running Port

$ sudo netstat -tulnp | grep 3000
tcp        0      0 127.0.0.1:3000          0.0.0.0:*               LISTEN      3234934/node /home/

You can stop NodeJS app with the following command.

$ pm2 stop app.js
[PM2] Applying action stopProcessId on app [app.js](ids: [ 0 ])
[PM2] [app](0) ✓
┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id  │ name   │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0   │ app    │ default     │ N/A     │ fork    │ 0        │ 0      │ 0    │ stopped   │ 0%       │ 0b       │ ubuntu   │ disabled │
└─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

Install Nginx Web Server

sudo apt update
sudo apt install nginx
systemctl status nginx

Create a Virtual Host

sudo vim /etc/hosts
IP - Domain

sudo vim /etc/nginx/sites-available/app.example.com

server {

    server_name app.example.com;
    index index.html index.htm;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    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;
    }
}

Enable newly created virtual host.

sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

sudo pm2 start next
sudo pm2 restart next
sudo pm2 log next
sudo systemctl restart nginx.service
sudo systemctl status nginx.service

Verify Node JS service after applying ProxyPass

$ curl app.example.com
Hello World

Conclusion

That’s all you need to know about how to install and configure Node.js with Nginx on Ubuntu 20.04. I hope the above article helps to set up Node.js with Nginx on Ubuntu 20.04. There are more tutorials that will go into a deeper explanation of using NodeJS and Nginx thoroughly, but this is a simple article to just get familiar with setting up Node.js with Nginx on Ubuntu 20.04.

Reference

https://www.nginx.com/
https://nodejs.org/en/
https://nodejs.org/en/download/

 

Avatar photo

Asif Khan

Responsible and proactive professional with more than 13 years of experience in IT systems, open source software applications, DevOps, Linux systems, and cloud operations. My main goals are to automate things, keep them safe, and make sure they are strong. I am very good at planning and building the infrastructure for services that people really want. I was drawn to the fast-paced world of cloud computing because it has resources that can be scaled up or down as needed. One of my best skills is being able to use a lot of different DevOps tools to set up, release management, and microservices ecosystems, as well as for provisioning, orchestration, and configuration management.