When you scale a web application, moving from shared hosting or small VPS instances to a production dedicated server is a major milestone. A dedicated server gives you bare-metal access to all CPU cores and RAM, ensuring your application runs without the "noisy neighbor" effect. However, raw power isn't enough. Node.js is single-threaded by nature. To truly harness a dedicated server's multi-core architecture and ensure 24/7 uptime, you must pair Node.js 22 with a robust process manager like PM2. In this Leo Servers tutorial, we will walk you through setting up a bulletproof, production-ready Node.js 22 environment. We will cover security prerequisites, installation, process management, and how to utilize PM2's cluster mode to maximize your dedicated hardware.
What You'll Learn
Why Node.js 22 and PM2?
Prerequisites
Step 1 β Secure and Update Your Dedicated Server
Step 2 β Install Node.js 22 via NodeSource
Step 3 β Install PM2 Globally
Step 4 β Prepare a Sample Node.js Application
Step 5 β Configure PM2 for Production (Cluster Mode)
Step 6 β Ensure 24/7 Uptime with PM2 Startup
Step 7 β Essential PM2 Commands for Sysadmins
Bonus Pro-Tip: Setting Up Nginx as a Reverse Proxy
Why Node.js 22 and PM2?
Before diving into the command line, it is crucial to understand why this stack is the industry standard for enterprise applications:
- Node.js 22 (LTS): The V8 JavaScript engine in Node 22 brings significant performance upgrades, native WebSocket support, and stable pattern matching. Relying on an LTS (Long Term Support) release guarantees vital security patches for your production environment.
- PM2 (Process Manager 2): If a Node.js app crashes in production, it stays down unless something restarts it. PM2 acts as a daemon that monitors your application, automatically restarts it upon failure, captures logs, and allows you to run multiple instances of your app across all CPU cores (Cluster Mode) with zero downtime reloads.
Prerequisites
To follow this guide, you will need:
(Ubuntu 24.04 / 22.04 LTS or Debian)
user privileges
command line knowledge
(Terminal, PuTTY, PowerShell)
Step 1: Secure and Update Your Dedicated Server
Never install production software on an outdated operating system. The first step on any new dedicated server is to update the package repositories and upgrade existing software to patch known vulnerabilities.
Connect to your server via SSH:
ssh username@your_server_ip
Once logged in, run the following commands to update your system:
sudo apt update
sudo apt upgrade -y
Next, ensure you have the necessary baseline utilities installed:
sudo apt install curl dirmngr apt-transport-https lsb-release ca-certificates -y
Step 2: Install Node.js 22 via NodeSource
Ubuntu's default software repositories often contain older versions of Node.js. Because we specifically need Node.js 22 for our production environment, we will use the official NodeSource package repository.
First, download and execute the NodeSource setup script for Node.js 22. This script automatically configures the GPG keys and adds the correct repository to your system.
curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
Once the repository is successfully added, install Node.js. (Note: The nodejs package from NodeSource automatically includes npm, the Node Package Manager).
sudo apt install -y nodejs
Verify the Installation
To confirm that the installation was successful and that you have the correct versions, run:
node -v
# Output should be: v22.x.x
npm -v
# Output should be: 10.x.x (or higher)
Step 3: Install PM2 Globally
With Node.js and npm installed, we can now install PM2. Because PM2 is a tool that manages applications system-wide, we must install it globally using the -g flag.
sudo npm install pm2@latest -g
Verify PM2 is installed correctly by checking its version:
pm2 -v
Step 4: Prepare a Sample Node.js Application
If you already have your application files on the server (usually in a directory like /var/www/your_app), you can skip this step. We will create a lightweight Express.js server to demonstrate PM2.
Create a directory for your application and navigate into it:
mkdir -p /var/www/leoservers-demo
cd /var/www/leoservers-demo
Initialize a new Node.js project and install Express:
npm init -y
npm install express
Create an app.js file:
nano app.js
Paste the following code into the file:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send(`Hello from LeoServers! Node.js is running on worker process: ${process.pid}`);
});
app.listen(port, () => {
console.log(`Production app listening at http://localhost:${port}`);
});
Save and exit the file (In Nano, press CTRL+O, Enter, then CTRL+X).
Step 5: Configure PM2 for Production (Cluster Mode)
Here is where the power of your dedicated server comes into play. PM2's Cluster Mode allows you to automatically spawn multiple instances based on the number of CPU cores available.
Instead of starting the app via a simple CLI command, the best practice for production is to use an Ecosystem Configuration File.
Generate an ecosystem file:
pm2 init simple
This creates an ecosystem.config.js file. Open it for editing:
nano ecosystem.config.js
Replace the contents with the following production-optimized configuration:
module.exports = {
apps : [{
name : "leoservers-app",
script : "./app.js",
instances : "max", // Utilizes all available CPU cores
exec_mode : "cluster", // Enables load balancing
env_production: {
NODE_ENV: "production",
PORT: 3000
}
}]
}
Start your application using the ecosystem file in production mode:
pm2 start ecosystem.config.js --env production
When you run this, PM2 will output a table showing your application running multiple times. If your dedicated server has 16 cores, you will see 16 application processes running concurrently!
Step 6: Ensure 24/7 Uptime with PM2 Startup
Currently, your application is running perfectly. However, if your dedicated server reboots for hardware maintenance or OS updates, PM2 will not start automatically.
We need to generate a startup script that tells Ubuntu's systemd to launch PM2 on boot. Run the following command:
pm2 startup
PM2 will analyze your operating system and output a specific command at the bottom of your terminal. You must copy and paste that exact output into your terminal. It will look something like this:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u your_username --hp /home/your_username
Execute that copied command. Once it completes successfully, save your current PM2 application list so it knows what to boot up:
pm2 save
Your Node.js application is now incredibly resilient. It will survive app crashes (PM2 will restart it immediately) and server reboots (systemd will wake up PM2, and PM2 will load the saved list).
Step 7: Essential PM2 Commands for Sysadmins
Managing your application going forward is simple. Here is a cheat sheet of the most vital PM2 commands you will use on your LeoServers dedicated machine:
- View all running applications:
pm2 list - Monitor CPU and RAM usage in real-time:
pm2 monit - View application logs:
pm2 logs(orpm2 logs leoservers-appfor a specific app) - Restart the application (Zero Downtime):
pm2 reload leoservers-app - Stop the application:
pm2 stop leoservers-app - Delete the application from PM2:
pm2 delete leoservers-app
pm2 reload restarts workers one by one, ensuring your site experiences zero downtime. pm2 restart kills all processes at once and boots them back up.
Bonus Pro-Tip: Setting Up Nginx as a Reverse Proxy
Right now, your application is running on port 3000. It is a massive security risk to run Node.js as a root user to bind it directly to port 80 (HTTP) or 443 (HTTPS).
The industry standard is to place a robust web server like Nginx in front of Node.js. Nginx will listen on ports 80/443, handle SSL certificates, serve static files efficiently, and forward dynamic requests to your PM2 cluster on port 3000.
Install Nginx:
sudo apt install nginx -y
Create a new configuration block for your domain:
sudo nano /etc/nginx/sites-available/yourdomain.com
Add the following reverse proxy configuration:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
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;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Enable the site and restart Nginx:
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Now, when visitors go to yourdomain.com, Nginx seamlessly hands the traffic to your heavily optimized Node.js + PM2 cluster.
Conclusion
Deploying Node.js 22 with PM2 on a dedicated server transforms a simple script into an enterprise-grade backend infrastructure. By leveraging PM2's cluster mode alongside an Nginx reverse proxy, you are maximizing the ROI of your server's hardware while guaranteeing the high availability your users demand.
Looking for Bare-Metal Performance?
If you are looking for bare-metal performance with zero compromises, check out the high-performance dedicated servers at Leo Servers. Start deploying your enterprise applications today with total control.
View Dedicated Servers