Deploying a Node.js app into production requires more than simply running npm start. You need a process manager, a reverse proxy, SSL support, and a clean deployment workflow. In this tutorial, you'll learn how to deploy a Node.js API or application on a Linux VPS using PM2, Nginx, and free SSL certificates from Let’s Encrypt.
This stack is lightweight, reliable, and production-ready.
You should have:
Assumptions in this guide:
SSH into your VPS:
ssh username@your-server-ip
Update packages:
sudo apt update && sudo apt upgrade -y
sudo apt install -y nodejs npm git
node -v
npm -v
(Optional: install via NVM if you prefer full version control.)
Navigate to a deployment directory:
cd /var/www\sudo mkdir my-node-app
sudo chown $USER:$USER my-node-app
cd my-node-app
Clone the repo:
git clone https://github.com/your/repo.git .
npm install
Run it locally to confirm:
npm start
Your API should now run at http://localhost:3000.
sudo npm install -g pm2
Start the app:
pm2 start server.js --name "my-node-app"
Save process list:
pm2 save
pm2 startup
Run the command PM2 prints, then save again:
pm2 save
Your Node.js app now auto-starts after system reboot.
Install Nginx:
sudo apt install -y nginx
Create a server block:
sudo nano /etc/nginx/sites-available/my-node-app
Add:
server { listen 80; server_name api.yourdomain.com;location / { proxy_pass http://127.0.0.1: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 the config:
sudo ln -s /etc/nginx/sites-available/my-node-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Your app is now live at: http://api.yourdomain.com
Install Certbot:
sudo apt install certbot python3-certbot-nginx
Run certificate setup:
sudo certbot --nginx -d api.yourdomain.com
Choose “Redirect to HTTPS.”
Auto-renewal runs automatically, but you can test it:
sudo certbot renew --dry-run
Now your app is live at: https://api.yourdomain.com
When you push new updates to GitHub:
cd /var/www/my-node-app
git pull origin main
npm install # if dependencies changed
npm run build # optional
pm2 restart my-node-app
This takes seconds and is safe for production.
PM2 gives useful tools:
pm2 logs my-node-app
pm2 monit
pm2 restart my-node-app
You now have a fully deployed production-ready Node.js app using:
This deployment stack powers everything from small APIs to large-scale apps, and is easy to maintain.