How to deploy a Next Js application on a VPS with PM2 and Nginx

How to deploy a Next Js application on a VPS with PM2 and Nginx

May 22, 2025

Here’s a step-by-step walkthrough for deploying your Next.js App Router application on an Ubuntu VPS, managed by PM2 and fronted by Nginx:


1. VPS Prep & SSH Access

  1. Provision your VPS, e.g. Ubuntu 22.04 LTS on DigitalOcean, AWS EC2, etc.

  2. Open SSH port (22) in your provider’s dashboard (or change to a custom port if you prefer).

  3. SSH in:

    ssh root@your_server_ip
    

2. System Update & Node.js Installation

# Update packages
apt update && apt upgrade -y

# Install curl, build tools
apt install -y curl build-essential

# Install Node.js (LTS) via NodeSource
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
apt install -y nodejs
  • Verify versions

    node -v    # e.g. v18.x
    npm -v     # e.g. 9.x
    

3. Create Deployment User (Optional but Recommended)

adduser deployer
usermod -aG sudo deployer
  • Then exit root and SSH in as deployer.

4. Clone & Install Your Next.js App

  1. Navigate to your preferred directory, e.g.:

    mkdir -p ~/apps/nextjs-app && cd ~/apps/nextjs-app
    
  2. Clone your repo (or pull latest):

    git clone https://github.com/yourusername/your-nextjs-repo.git .
    
  3. Install dependencies & build:

    npm ci          # or yarn install --frozen-lockfile
    npm run build
    

5. Configure PM2

  1. Install PM2 globally:

    npm install -g pm2
    
  2. Start Next.js in production:

    pm2 start npm --name "nextjs-app" -- run start
    
  3. Generate PM2 ecosystem file (optional, for env vars & clustering):

    pm2 ecosystem
    

    Edit ecosystem.config.js:

    module.exports = {
      apps: [
        {
          name: "nextjs-app",
          script: "npm",
          args: "run start",
          cwd: "/home/deployer/apps/nextjs-app",
          instances: "max",
          exec_mode: "cluster",
          env: {
            NODE_ENV: "production",
            // Add other env vars here
          }
        }
      ]
    };
    
  4. Start via ecosystem:

    pm2 start ecosystem.config.js
    
  5. Persist PM2 across reboots:

    pm2 save
    pm2 startup systemd
    # Follow the printed instructions to enable the service
    

6. Install & Configure Nginx

  1. Install Nginx:

    sudo apt install -y nginx
    
  2. Create Nginx site file at /etc/nginx/sites-available/nextjs-app:

    server {
      listen 80;
      server_name your_domain_or_ip;
    
      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;
      }
    
      # Optional: serve static assets directly
      location /_next/static/ {
        alias /home/deployer/apps/nextjs-app/.next/static/;
        access_log off;
        expires max;
      }
    }
    
  3. Enable & restart:

    ln -s /etc/nginx/sites-available/nextjs-app /etc/nginx/sites-enabled/
    nginx -t
    systemctl reload nginx
    

7. (Optional) Secure with Let’s Encrypt SSL

  1. Install Certbot:

    apt install -y certbot python3-certbot-nginx
    
  2. Obtain & configure cert:

    certbot --nginx -d your_domain.com -d www.your_domain.com
    
  3. Auto-renewal (installed by default as a cron job).


8. Monitoring & Logs

  • View PM2 status:

    pm2 status
    
  • Inspect logs:

    pm2 logs nextjs-app --lines 100
    
  • Restart on code changes (dev only):

    pm2 start npm --name "nextjs-dev" --watch -- run dev
    

Recap of Key Commands

# System & Node
apt update && apt upgrade -y
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
apt install -y nodejs nginx

# Clone & build
git clone repo .
npm ci && npm run build

# PM2
npm install -g pm2
pm2 start npm --name "nextjs-app" -- run start
pm2 save && pm2 startup systemd

# Nginx
# create /etc/nginx/sites-available/nextjs-app (as above)
ln -s /etc/nginx/sites-available/nextjs-app /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

# SSL (optional)
apt install -y certbot python3-certbot-nginx
certbot --nginx -d your_domain.com

With this setup, your Next.js application is running under PM2, automatically restarts on crashes or reboots, and is served securely (if using SSL) behind Nginx.

Comments

No comments yet.

Related Posts