How to Deploy a Next.js App on a VPS with Nginx and PM2

Deploying a Next.js application to production can feel complicated if you’ve only worked locally. But once you understand the process, it’s actually very structured.

In this guide, you’ll learn how to deploy a Next.js app on a VPS using Nginx and PM2, step by step. This setup is widely used in production because it gives you:

  • Full control over your server
  • Better performance compared to shared hosting
  • Ability to scale and optimize
  • No platform lock-in

By the end of this guide, your Next.js app will be live with:

  • Nginx as a reverse proxy
  • PM2 for process management
  • SSL (HTTPS) enabled
  • Production-ready configuration

Prerequisites

Before you start, you need:

  • A VPS (Ubuntu 22.04 recommended)
  • Domain name pointing to your server
  • Basic knowledge of SSH
  • Node.js installed (v18+ recommended)

Step 1: Connect to Your VPS

ssh user@your-server-ip

Update your system:

sudo apt update && sudo apt upgrade -y

Step 2: Install Node.js

Install Node.js:

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

Verify:

node -v
npm -v

Step 3: Upload Your Next.js App

You can:

  • Use Git clone
  • Upload via SCP
  • Pull from GitHub

Example:

git clone https://github.com/yourrepo/nextjs-app.git
cd nextjs-app

Install dependencies:

npm install

Step 4: Build the App

npm run build

This creates an optimized production build.


Step 5: Install PM2

PM2 keeps your app running in background.

sudo npm install -g pm2

Start app:

pm2 start npm --name "nextjs-app" -- start

Save process:

pm2 save
pm2 startup

Step 6: Install Nginx

sudo apt install nginx -y

Start Nginx:

sudo systemctl start nginx

Step 7: Configure Nginx Reverse Proxy

Create config:

sudo nano /etc/nginx/sites-available/nextjs

Paste:

server {
    listen 80;
    server_name 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;
    }
}

Enable config:

sudo ln -s /etc/nginx/sites-available/nextjs /etc/nginx/sites-enabled/

Test:

sudo nginx -t

Restart:

sudo systemctl restart nginx

Step 8: Configure Firewall

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

Step 9: Add SSL with Let’s Encrypt

Install Certbot:

sudo apt install certbot python3-certbot-nginx -y

Run:

sudo certbot --nginx -d yourdomain.com

Step 10: Verify Deployment

Visit:

👉 https://yourdomain.com

Your Next.js app should be live.


Performance Optimization Tips

  • Enable caching in Nginx
  • Use CDN (Cloudflare)
  • Optimize images
  • Use gzip compression

Common Errors

Port Already in Use

Fix:

lsof -i :3000

Nginx 502 Bad Gateway

Check PM2:

pm2 logs

Best Practices

  • Use environment variables
  • Monitor logs
  • Keep dependencies updated
  • Use CI/CD pipeline

FAQs

Can I deploy without PM2?

Yes, but not recommended.

Can I use Apache instead of Nginx?

Yes, but Nginx is faster.


Final Thoughts

Deploying a Next.js app on a VPS with Nginx and PM2 is one of the best ways to host modern web apps with full control and scalability


Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *