DigitalOceanTutorial2 min read

How Do I Deploy a Node.js App on DigitalOcean with PM2?

Deploy a Node.js application on a DigitalOcean Droplet using PM2 for process management, auto-restart, and zero-downtime reloads.

Server racks and cloud infrastructure

The Stack

A typical Node.js deployment on DigitalOcean uses three layers: your app running on a port (e.g. 3000), PM2 to keep it alive and restart on crashes, and Nginx as a reverse proxy on port 80/443. This tutorial covers the PM2 layer.

Step 1 — Install Node.js

On your Droplet, install Node.js 20 LTS via NodeSource:

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node --version

Step 2 — Upload Your Application

Clone from Git or copy files to /var/www/myapp:

git clone https://github.com/you/myapp.git /var/www/myapp
cd /var/www/myapp
npm ci --production

Create a .env file with production variables. Never commit secrets to Git.

Step 3 — Install and Configure PM2

sudo npm install -g pm2

Start your app:

pm2 start npm --name "myapp" -- start

Or point directly at your entry file:

pm2 start server.js --name "myapp"

Verify it is running:

pm2 status
pm2 logs myapp

Step 4 — Persist PM2 Across Reboots

pm2 startup systemd
pm2 save

The startup command prints a line you may need to copy and run with sudo. After that, PM2 restores all saved processes whenever the Droplet reboots.

Step 5 — Use an Ecosystem File

For production, create ecosystem.config.js in your project root:

module.exports = {
  apps: [{
    name: 'myapp',
    script: 'server.js',
    instances: 1,
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    }
  }]
};

Deploy with: pm2 start ecosystem.config.js

Step 6 — Zero-Downtime Reloads

When you push new code:

cd /var/www/myapp
git pull
npm ci --production
pm2 reload myapp

reload restarts the process gracefully without dropping active connections.

PM2 Commands Cheat Sheet

  • pm2 status — list all processes
  • pm2 logs — stream logs
  • pm2 monit — live CPU/memory dashboard
  • pm2 restart myapp — hard restart
  • pm2 delete myapp — remove from PM2

Pair PM2 with Nginx as a reverse proxy and Certbot for SSL to complete your production setup.