Deploying a Node App on Ubuntu 22.04 for Optimal Performance

If you’re a developer seeking guidance on Deploying a Node App on Ubuntu 22.04, you’re in the right place. In this guide, we’ll walk you through the process step by step, ensuring your app is up and running smoothly.

Before we dive into Deploying a Node App on the server it’s essential to have Ubuntu 22.04 ready. Begin by installing Ubuntu 22.04 on your server. You can find detailed installation instructions – Here

Update and Upgrade: After installation, update and upgrade your system using the following commands:

sudo apt update
sudo apt upgrade -y

Connect to the server using SSH

DigitalOcean droplets are created with a root user, and with our SSH keys added, we can now log in seamlessly without the need for a password. Like magic! use the below command and replace the IP with your droplet IP.

# Note - Replace the below IP with your droplet IP
ssh [email protected] #

The first time you log in, it’s highly probable that you’ll be prompted to confirm if you want to proceed with the connection. Type yes to continue, and you’ll see something similar to the following:

ssh [email protected]

The authenticity of host ' (' can't be established.
ED25519 key fingerprint is SHA256:b343x4YymYEgzpoFfA7pGthtKPKz78NnFY3wSbtJzsU.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '' (ED25519) to the list of known hosts.
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-67-generic x86_64)

 * Documentation:
 * Management:
 * Support:

  System information as of Fri Oct 20 09:58:16 UTC 2023

  System load:  0.42626953125     Users logged in:       0
  Usage of /:   6.8% of 24.05GB   IPv4 address for eth0:
  Memory usage: 22%               IPv4 address for eth0:
  Swap usage:   0%                IPv4 address for eth1:
  Processes:    93

Expanded Security Maintenance for Applications is not enabled.

142 updates can be applied immediately.
84 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

Enable ESM Apps to receive additional future security updates.
See or run: sudo pro status

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.


You can follow the link for the Initial server setup –

Create a new User with sudo and SSH permission.

For Deploying a Node App on our server, First we’re going to add a new user with sudo privileges. To do this, run the following command while logged into your droplet:

#You can choose any username you want here
adduser kahnu

Adding user `kahnu' ...
Adding new group `kahnu' (1000) ...
Adding new user `kahnu' (1000) with group `kahnu' ...
Creating home directory `/home/kahnu' ...
Copying files from `/etc/skel' ...
New password: 
Retype new password: 
passwd: password updated succeThe nano editor allows us to copy-paste your SSH key into the new file, then press control + X to exit. Type Y to save the file, and press enter to confirm the file name.ssfully
Changing the user information for kahnu
Enter the new value, or press ENTER for the default
	Full Name []: Kahnu Charan Swain
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] y

In order to run some of the commands on the server, such as restarting services, we need to add our new user to the sudo group. Do this by running the following command:

usermod -aG sudo kanhu

Add your SSH key for the new user

This step is optional, as some VPS providers may automatically include your SSH key in the Ubuntu server OS during the server creation process. If this hasn’t been done, you can add it manually. For Digital Ocean users who have already configured their SSH key, you can proceed with the following command to enable SSH access.

# Become the new user
su - kahnu

#Give ssh access to the new user
#rsync --archive --chown=yournewusername:yournewusername ~/.ssh /home/yournewusername
rsync --archive --chown=kanhu:kanhu ~/.ssh /home/kanhu

If you are not using Digital Ocean or did not configure SSH during server creation, proceed with the next step:

# Become the new user
su - kahnu

Next, verify if the SSH directory exists or not by using the following command:

cd ~/.ssh

If you find a file named “authorized_keys” using the above command, simply copy your system SSH key and paste it here.

#oprn system public ssh key and copy whole key content and paste it
cat ~/.ssh/

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDcNkHpaV9z9EDLZP6gJ6dG+0hZdtJPlfES0J7ldZRr2ZnhMlHM9WNCM6Lp7/zb6RS4G5CHtDfUQxH2+gRGGPdnls1GvCVNntoLyO7Y9Azr1W4qrgWFBcX78vB/hFv/EVEh0vTJCrL/DKrt/LGRfXyv1P1t9tCSDTfG0XadTkfoKo7obxspRUHZ0HUOgFzX09LqQ5rvCKNTYiWdRHCjJXz2ycWjZGms5mXUIZJ4vIPil3AwBqVqllprGidNFqqK6ktXJmOZlX/0ZU0QZ8szdsK6tuCjeU5Qz0QuTJdfDxt+MqCw0W0fF46TQoThMSz7zvOBnGyZi3YU3F49INe/aMTxo/5y0s1g2w/Ils+NSQ/wIy0sTPZEFgCNoUsGhKKEhkyJ2DNm0HtM6qfprKvnUoznXHc2ebLlGdmL9/1kFp2bU2SHRcQ39wouR0Vz2G1we/W6X8h8vDH/lP2DqeJzVd4ojvO4LAdJhrBnZXLHN6xBiHX/ISDvGsXlT3k= [email protected]

If you don’t already have an SSH directory, you can create one by using the following command. Afterwards, you can configure your SSH key by pasting it into the file

# Create a new directory for SSH stuff
mkdir ~/.ssh

# Set the permissions to only allow this user into it
chmod 700 ~/.ssh

# Create a file for SSH keys
nano ~/.ssh/authorized_keys

“You can use the nano editor to copy and paste your SSH key into the new file. To save and exit, press Ctrl + X, then type Y to confirm the save, and press Enter to confirm the file name.”

# Set the permissions to only allow this user to access it
chmod 600 ~/.ssh/authorized_keys

# Stop acting as the new user and become root again

Now you can log in to your server with your new username

# Note - Replace the below IP with your droplet IP and kahnu with your username
ssh [email protected]

Set up a basic firewall

For Deploying a Node App we’ll set up a basic firewall configuration. This will restrict all traffic except for standard web traffic on ports 80 (HTTP) and 443 (HTTPS), and it will allow SSH logins.

To configure the firewall (known as ufw), we’ll execute three commands and then activate it. Please input the following commands after logging into the server:

NOTE: Do not use this command if your server is hosted on AWS, GCP, or any other cloud service provider. This instruction specifically applies to Digital Ocean servers. Please consult the documentation of your respective service provider before using this command.

# Enable OpenSSH connections
sudo ufw allow OpenSSH

# Enable HTTP traffic
sudo ufw allow http

# Enable HTTPS traffic
sudo ufw allow https

# Turn the firewall on
sudo ufw enable

When you enable ufw, you’ll get a notice that enabling the firewall might disrupt your connection. No need to worry about that — you’ve successfully enabled SSH connections. To check the status of the firewall, run the below command which will give you the following:

#To check UFW status
sudo ufw status

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
80/tcp                     ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
80/tcp (v6)                ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)          

Deploying a Node App – Set up Project

Outlined below are the fundamental steps for Deploying a Node App on an Ubuntu server using Nginx and PM2.

Now that the server is configured, let’s proceed with installing our application. For Deploying a Node App on the server we need a copy of our app to this server, here we’ll utilize Git to get our app.

Typically, the Ubuntu OS provided by VPS service providers comes with Git pre-installed. To verify if Git is installed, use the following command.

#Check if Git is already installed
git --version

#The expected output (the version number may vary)
git version 2.34.1

If it’s not installed, you can use the command below to install it:

#Install git
sudo apt-get install git

#Check the installed version(the version number may vary)
git version 2.34.1

Set up Node.js.

Deploying a Node App is a little more complex than Git because there are several different versions of Node that are used in production environments. Hence, it’s essential to ensure that apt-get is updated with the correct version for our application prior to installation.

We’ve previously provided a guide on how to install Node.js on Ubuntu. Please refer to that post for instructions on installing Node.js. Here is the tutorial

Once it’s complete, we can verify that node is available by running the below command

node -v


Clone the app

After setting up the node js, it’s time to Deploying a Node App, ensuring it’s accessible to users

Next, we’ll proceed to clone our application to the server using Git. The location of the installation doesn’t matter. Let’s create a directory for the app in our user’s home directory and clone the app into a folder named after our domain. This way, it’s easy to identify which app is associated with which domain.

# Make sure you’re in your home directory
cd ~

# Create the new directory and move into it
mkdir apps
cd apps/

# Clone your app into a new directory named for your domain
git clone

The command above will generate a new directory named “apps/” in your server’s home directory.

Test the app

To ensure your app is installed and functioning properly, navigate into the newly created folder and initiate it. To start the app use the below command

#Go to your app folder
cd ~/apps/

#Install node modules 
npm i

#Start your server
node server.js

Note: In the example app, the main file is located at Depending on your app’s setup, you may need to modify your start command accordingly.

The example app is set to listen at http://localhost:3001 . To test if it’s functioning, you can open a new Terminal session, log into your server, and make a curl request to the app.

#Change the port according to your app
curl http://localhost:3001

Deploying a Node App Using a Process Manager

After Deploying a Node App, while manually starting the app is technically sufficient for deployment, in the event of a server restart, this would necessitate manually initiating the app once more.

In production environments, it’s desirable to minimize, if not entirely remove, manual steps for deploying the app. Therefore, we’ll employ a process manager named PM2 to oversee the execution of our app. This provides additional advantages such as convenient access to logs, and straightforward control over starting, stopping, and restarting the app.

Additionally, PM2 enables us to automate the app’s startup upon server restarts, reducing one less task to manage.

Install PM2

Unlike the previously installed tools, pm2 is a Node package. It is installed using the npm command, which serves as the default package manager for Node.js.

#Deploying a Node App with pm2
sudo npm install -g pm2

The use of -g ensures that pm2 is installed globally, which is essential for its proper functionality.

Start your app using PM2

With PM2 installed, we can now start the app like this:

#Make sure you're in your project folder
cd ~/apps/ 

#Then use the below command to start your app with PM2
pm2 start server.js --name myNodeApp

#Now you can check is your app is running or not 
curl http://localhost:3001

{"status":true,"message":"Welcome To Node Server"}

Start your app automatically when the server restarts

We’re nearly finished with getting the app up and running, just one more step remains. To ensure that PM2 restarts our app after a server reboot, we need to perform a two-step process. Let’s begin by executing the command pm2 startup systemd.

To automatically start your app when the server restarts using PM2, follow the below command

pm2 startup

You will receive a message with a command to run. Copy and paste the provided command into the terminal and press Enter. This command sets up PM2 to start on boot.

After executing the command, you should see a message indicating that PM2 has been successfully configured to start on boot. Now, your app managed by PM2 will automatically start when the server restarts.

If you want to learn more about pm2 – Click Here

Connect your APP to a domain

Step 1 – Point Your Domain to the App

After Deploying a Node App, it is time to link your Node.js application to a domain, adhere to these steps:

  1. Navigate to the “DNS” section within your domain provider’s settings.
  2. Create a DNS record dedicated to your Node.js application. This is typically an ‘A’ record pointing to your server’s IP address.

Please remember that DNS changes may take a while to propagate globally. Allow some time for these alterations to take full effect worldwide.

Deploying a Node App - DNS Setting

Step 2 – Setup Nginx

Nginx is a web server that will act as a reverse proxy to forward requests to your Node.js application. If it’s not already installed, you’ll need to do this first.

sudo apt update
sudo apt install nginx

Step 3 – Setup Config for your domain

Each domain or site you host on your server needs its own Nginx configuration file. This file contains the settings specific to that site. Use the below command to create an nginx config file for your domain name

sudo nano /etc/nginx/sites-available/

it will open a default editor copy the below code to this file, remember to change the port and domain name.

server {
    listen 80;

    location / {
        proxy_pass http://localhost:3001;
        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 the Nginx Configuration

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

Step 4 – Check Nginx configuration and reload the Nginx

sudo nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

To apply the changes in your Nginx configuration restart the Nginx.

sudo systemctl reload nginx
Deploying a Node App - Response

Get a Free SSL Certificate With Certbot

It’s clear that Deploying a Node App on Ubuntu is a straightforward task. Now, let’s elevate security by incorporating an SSL layer Certbot now advises using the PIP package manager instead of the older python-certbot-apache package.

Step 1: First, install PIP:

sudo apt install python3 python3-venv libaugeas0

Step 2: Set up a virtual environment:

sudo python3 -m venv /opt/certbot/

sudo /opt/certbot/bin/pip install --upgrade pip

Step 3: Install Certbot on Nginx or Apache:

sudo /opt/certbot/bin/pip install certbot certbot-nginx

sudo /opt/certbot/bin/pip install certbot certbot-apache

Step 4: Create a symlink to ensure Certbot runs:

sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

Step 5: Having successfully configured Certbot on our Ubuntu server, the next step is to install SSL for our domain.

sudo certbot --nginx

sudo certbot --apache

It will request certain information. Provide it and then wait a few moments for the SSL installation process to complete for your domain.

sudo certbot --nginx

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): [email protected]

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
Account registered.

Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 
Requesting a certificate for

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/
Key is saved at:         /etc/letsencrypt/live/
This certificate expires on 2024-01-24.
These files will be updated when the certificate renews.

Deploying certificate
Successfully deployed certificate for to /etc/nginx/sites-enabled/
Congratulations! You have successfully enabled HTTPS on

- The certificate will need to be renewed before it expires. Certbot can automatically renew the certificate in the background, but you may need to take steps to enable that functionality. See for instructions.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:
 * Donating to EFF:          
Deploying a Node App - HTTPS Response

Deploying a Node App on a different VPS provider, you can follow these steps to ensure a seamless deployment without any errors.

Leave a Comment