Skip to main content

Command Palette

Search for a command to run...

How to Deploy a Node.js App on a Linux VPS: Complete Beginner's Guide

Updated
9 min read
How to Deploy a Node.js App on a Linux VPS: Complete Beginner's Guide
I
Business Development Manager with over six years of experience in client and key account management, specializing in leading complex projects across diverse organizational structures. Skilled in coordinating cross-functional teams, maintaining strong client relationships, and ensuring transparent communication throughout all project stages. Focused on delivering measurable results aligned with business objectives through effective project management, workflow optimization, and data-driven decision-making. Experienced in handling objections, resolving conflicts, and balancing stakeholder interests while identifying and mitigating risks. Strong background in pre-sales activities, including consultations, proposal development, pricing, and contract negotiations, with a proven ability to increase conversion rates through tailored value propositions, upselling, and cross-selling. Possesses solid technical understanding of IT infrastructure, supports team development through training and collaboration, and promotes customer advocacy and cybersecurity awareness.

A Node.js project can run on shared hosting only in limited cases. Once the app needs its own process, custom ports, background work, WebSocket support, or direct control over environment variables, a VPS becomes the more practical option.

This guide shows how to deploy Node.js app on VPS with a clean beginner friendly workflow. You will prepare the Linux server, install Node.js, upload the app, run it with a process manager, place Nginx in front of it, add SSL, and check the live result.

You will also see how to run Node.js on VPS without leaving the app attached to an open terminal. The goal is not just to make the app respond once. The goal is to keep it running after logout, reboot, and normal production traffic.

By the end, you will understand the main parts of a Node.js VPS deployment and know what to check before you send users to the new server.

Prerequisites Before You Start

Before you begin, make sure your app can run locally. It should have a working "package.json", a start script, and a clear list of required environment variables. If the app needs a database, Redis, file storage, or external API keys, prepare those details before deployment.

You also need SSH access to a Linux VPS. Ubuntu or Debian works well for most beginner deployments. A Linux VPS from BlueVPS can be used for this type of setup if you want a server where you control the runtime, Nginx, firewall, and deployment flow.

Prepare these items before you start the Node.js server setup:

  1. VPS IP address.
  2. SSH user with sudo access.
  3. Domain name and DNS access.
  4. Git repository or archived project files.
  5. Production environment variables.
  6. App port, such as '3000'.
  7. Database access if the app uses one.
  8. SSL plan with Let's Encrypt or another provider.

You should also decide how the app will start. Most production setups use a process manager such as PM2. PM2 keeps the Node.js process running and can restore it after a server reboot.

This guide uses Nginx as a reverse proxy. Visitors will open "https://example.com", and Nginx will forward requests to the Node.js app on '127.0.0.1:3000'.

How to Deploy a Node.js App on a Linux VPS Step by Step

Step 1. Connect to the VPS and Update the System

Start by connecting to the server through SSH. Replace "root" and "server_ip" with your real login details.

ssh root@server_ip

Update package lists and install the basic tools you will need.

sudo apt update
sudo apt install nginx curl git ufw

Create a separate user for the application. Running app files under a dedicated user keeps the setup cleaner than placing everything under "root".

sudo adduser --disabled-password --gecos "" deploy
sudo mkdir -p /var/www/node-app
sudo chown -R deploy:deploy /var/www/node-app

If your server already has a non root sudo user, you can use that user instead. The important point is simple: the app should have a clear owner, and you should know where its files live.

Step 2. Install Node.js and npm

Use an active LTS version of Node.js for production unless your project requires another supported version. This example uses Node.js 24, which is the current LTS line in 2026.

curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt install nodejs
node -v
npm -v

The commands "node -v" and "npm -v" confirm that the runtime and package manager are available.

Do not skip the version check. Many deployment problems come from a mismatch between the Node.js version used during development and the version installed on the VPS.

Step 3. Upload or Clone the Application

Move into the app directory as the deployment user.

sudo -iu deploy
cd /var/www/node-app

Clone your repository into the app folder. Replace the repository URL with your real project URL.

git clone https://github.com/your-name/your-app.git .

If you do not use Git, upload the project with SFTP or SCP instead. Keep the same structure that works locally. The server should contain "package.json", the source files, and any files required to build or run the app.

Check that the start script exists.

npm pkg get scripts

The output should include a command such as "start". If your app does not have a start script, add it in the project before deployment.

Step 4. Install Production Dependencies

Install dependencies on the VPS. Use "npm ci" if the project has a lock file. This gives a more predictable install than a fresh dependency resolution.

npm ci --omit=dev

If your project does not have "package-lock.json", use this command instead:

npm install --omit=dev

Some apps need a build step. This is common for frameworks that compile frontend assets or server bundles.

npm run build --if-present

The flag "--if-present" prevents an error when the project has no build script.

Step 5. Add Production Environment Variables

Most Node.js apps need environment variables. Common examples include "NODE_ENV", "PORT", database URLs, session secrets, API keys, and storage settings.

Create a production environment file only if your app expects one.

nano .env

Add the required values for your project. A simple example may look like this:

NODE_ENV=production
PORT=3000
APP_URL=https://example.com

Do not commit real production secrets to Git. Keep them on the server or in a secure deployment system.

After saving the file, confirm that the app directory still belongs to the deployment user.

ls -la

Step 6. Test the App Locally on the VPS

Before you add Nginx or SSL, start the app on its internal port.

PORT=3000 NODE_ENV=production npm start

Open a second SSH session and test the local response from the server.

curl -I http://127.0.0.1:3000

A successful response usually returns "200", "301", "302", or another expected status from your app. If the request fails, check the app logs in the first terminal.

Stop the app with "Ctrl+C" after the test. The next step will run it properly in the background.

Step 7. Run the App with PM2

Install PM2 globally.

sudo npm install pm2@latest -g

Go back to the app directory as the deployment user.

sudo -iu deploy
cd /var/www/node-app

Start the app with PM2.

PORT=3000 NODE_ENV=production pm2 start npm --name node-app -- start
pm2 status

Save the process list.

pm2 save

Create a startup service so PM2 can restore the app after reboot.

pm2 startup systemd

PM2 will print a command that starts with "sudo env". Copy that generated command and run it. Then save the process list again.

pm2 save

At this point, the VPS can host Node.js application processes without keeping your SSH session open.

Step 8. Configure Nginx as a Reverse Proxy

Nginx should receive public web traffic on port 80 and forward it to the Node.js app on port 3000.

Create a new Nginx site file.

sudo nano /etc/nginx/sites-available/node-app

Add this configuration. Replace "example.com" with your real domain.

server {
    listen 80;
    server_name example.com www.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Enable the site and reload Nginx.

sudo ln -sfn /etc/nginx/sites-available/node-app /etc/nginx/sites-enabled/node-app
sudo nginx -t
sudo systemctl reload nginx

The command "sudo nginx -t" must pass before you reload Nginx. If it fails, fix the reported line first.

Step 9. Point the Domain to the VPS

Open your DNS provider and create or update the A record for the domain. Point it to the VPS IP address.

Use one record for "example.com" and another for "www" if the site uses both.

After DNS starts resolving to the new server, test the domain in a browser. You can also check it from the VPS or your local terminal.

curl -I http://example.com

If the domain does not resolve yet, wait and check DNS again. Do not change random server settings while DNS is still updating.

Step 10. Add SSL with Certbot

Install Certbot and the Nginx plugin.

sudo apt install certbot python3-certbot-nginx

Request an SSL certificate for your domain.

sudo certbot --nginx -d example.com -d www.example.com

Certbot will update the Nginx configuration and add HTTPS support. After it finishes, open the site with "https".

Check that the app still works behind Nginx. Test login, forms, redirects, API calls, uploads, and any page that depends on absolute URLs.

Step 11. Review Firewall and Server Access

Allow SSH and web traffic through the firewall.

sudo ufw allow OpenSSH
sudo ufw allow "Nginx Full"
sudo ufw enable
sudo ufw status

Enable the firewall only after SSH access is allowed and tested. Use SSH keys for production access, and disable password login only when you are sure the correct user can connect with a key.

Keep the Node.js app behind Nginx whenever possible. The public site should use ports '80' and '443', while the app itself runs on '127.0.0.1'.

Step 12. Check Logs and Prepare Future Updates

Use PM2 logs to inspect runtime errors.

pm2 logs node-app

Check Nginx logs if the browser shows proxy or gateway errors.

sudo tail -n 100 /var/log/nginx/error.log

Save a simple update routine for future releases. A typical manual update looks like this:

sudo -iu deploy
cd /var/www/node-app
git pull
npm ci --omit=dev
npm run build --if-present
pm2 restart node-app --update-env
pm2 save

This keeps the deployment process repeatable. For a larger project, you can later move this flow into CI, but a clear manual process is enough for a first VPS deployment.

Conclusion

You have now completed the main steps of a Node.js VPS deployment. The server has Node.js, npm, Nginx, PM2, firewall rules, SSL, and a running application behind a reverse proxy.

The key part is the order. Install the runtime first, place the app in a clear directory, verify it on a local port, run it with PM2, then expose it through Nginx and HTTPS. This makes each problem easier to locate.

Now you know how to run Node.js on VPS in a production style setup. You can deploy updates with a repeatable command sequence, check logs when something fails, and keep the app online after logout or reboot.