Blog · WebJi® India

Deploy Next.js on a VPS

Quick answer: Deploy Next.js on a VPS by installing Node on Ubuntu, running npm run build, then starting the app with PM2 on port 3000. Nginx proxies that port and Certbot adds HTTPS. Server-rendered pages need that Node process; a static-only host cannot run them.
✓ In business since 2005✓ INR + GST billing✓ 24/7 Email Support — avg reply < 60 min
Close-up of rack-mounted servers with glowing blue and green status LEDs, shallow depth of field — deploy nextjs on vps

Why a static host cannot serve Next.js SSR

A production Next.js app that uses server rendering, route handlers or server actions is a Node process. next start listens on a port, usually 3000. A host that only stores HTML files never starts that process, so those routes never run.

A static export (output: 'export') is different: it is a folder of files, and a file host can serve it. If any page renders on request, you need the Node server this guide starts. Next.js hosting is the quoted alternative when you do not want to run the box yourself.

BuildWhat must stay runningStatic or cPanel file host
next start (server rendering)Node on port 3000Fails. Nothing executes the server.
Route handlers and server actionsThe same Node processFails. The request has no runtime.
output: 'export'Nothing. Files only.Works, if you really exported every page.

Linux shared L-Basic is ₹300 a month before 18% GST, read on 30 Oct 2026. It is cPanel file hosting, not a Next.js runtime. Do not point this guide at that plan.

Prepare Ubuntu before you deploy Next.js

Use a Linux VPS with root or sudo. VPS hosting at WebJi® is quoted by email before payment. There is no published Next.js monthly price.

  1. SSH in, then run sudo apt update && sudo apt upgrade -y.
  2. Install Node.js 20 or newer and confirm it with node -v and npm -v.
  3. Allow SSH before you enable the firewall: sudo ufw allow OpenSSH, sudo ufw allow 80/tcp, sudo ufw allow 443/tcp, then sudo ufw enable.
  4. Leave port 3000 closed. Nginx will be the only public door.

This step worked when node -v prints 20 or higher and sudo ufw status shows 22, 80 and 443, not 3000.

Close-up of rack-mounted servers with glowing blue and green status LEDs, shallow depth of field — deploy nextjs on vps

Build Next.js and keep it running with PM2

Put the app in a directory you own, for example /var/www/app. Copy environment variables onto the server. Do not commit them. Node.js hosting is the same runtime if you want the process quoted instead of installed by hand.

  1. Install dependencies with npm ci. Use npm install only when there is no lockfile.
  2. Build with npm run build. If it exits non-zero, fix the error before you start anything. npm build is not a Next.js script.
  3. Start production mode: pm2 start npm --name nextapp -- start. That runs next start, not the dev server.
  4. If next.config sets output: 'standalone', start node .next/standalone/server.js under PM2 instead of npm start.

You know it worked when curl -I http://127.0.0.1:3000 returns 200 and pm2 status shows nextapp as online. A connection refused means the process never bound that port.

Proxy the Next.js port with Nginx

Install Nginx with sudo apt install nginx -y. Create a site file, disable the default site, and proxy every path to the Node process. Do not alias /_next/ to a folder on disk. next start serves those hashed files itself, and a disk alias serves the wrong ones.

  • listen 80; and server_name set to your domain and www host.
  • location / with proxy_pass http://127.0.0.1:3000; and proxy_http_version 1.1;.
  • Send Host, X-Real-IP, X-Forwarded-For and X-Forwarded-Proto $scheme.
  • Set Upgrade $http_upgrade and Connection "upgrade" so upgraded connections are not dropped.

Test with sudo nginx -t, then sudo systemctl reload nginx. Open the domain over plain HTTP. You should see the same page curl showed on port 3000. A 502 means PM2 is down or the port in proxy_pass is wrong.

Add the domain and HTTPS with Certbot

Create an A record for the hostname to the VPS IPv4 address, and the same for www if you use it. Wait until dig +short yourdomain.com prints that address. Certbot will fail if the name still points elsewhere.

  1. Install the Nginx plugin: sudo apt install python3-certbot-nginx -y.
  2. Issue the certificate: sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com.
  3. Choose the redirect to HTTPS when asked.
  4. Check renewal with sudo certbot renew --dry-run.

You are done when the browser padlock matches your hostname and curl -I https://yourdomain.com returns 200. If the padlock shows but styles are missing, a leftover http:// asset is the cause, not the certificate.

Restart Next.js after a reboot or a new build

PM2 forgets its list on reboot unless you register it. Run pm2 startup, execute the command it prints, then pm2 save. Reboot once and SSH back in. pm2 status should show nextapp online without you starting it.

  • Logs — pm2 logs nextapp for the app, and /var/log/nginx/error.log for the proxy.
  • A new build — npm ci, then npm run build, and pm2 restart nextapp only if the build exits 0. Restarting first takes the live app down on a broken build.
  • Disk and certificates — a full disk stops writes and builds. An expired certificate is a failed renewal, which the dry-run above is meant to catch.

Email support@webji.services if you want the same steps run for you. Support is 24/7 in Hindi and English, and the average first reply is under 60 minutes. The office phone is not a support line.

Frequently Asked Questions

How do I deploy a Next.js app on a VPS?

Build on Ubuntu with npm run build, start next start under PM2 on port 3000, proxy that port in Nginx, and run Certbot for HTTPS. The app is live when curl against the public https URL returns 200.

Why does a static host fail for Next.js server rendering?

Server rendering needs a Node process. A host that only stores files never runs next start, so route handlers and server actions never execute. A full static export is the exception, because it has no server.

Do I need Nginx in front of Next.js?

Yes, for a public site. Nginx owns ports 80 and 443, terminates TLS, and proxies to 127.0.0.1:3000. Next.js can listen directly, but then you manage certificates on the app itself.

How do I keep Next.js running after a reboot?

Run pm2 startup, execute the command it prints, then pm2 save. After a reboot, pm2 status should list the app as online. Without those two commands the process is gone until you start it again.

How do I add HTTPS to a Next.js VPS?

Point the domain A record at the VPS, then run sudo certbot --nginx with that hostname. Confirm with a browser padlock and curl -I on https. Test renewal with sudo certbot renew --dry-run.

How much RAM does a Next.js VPS need?

WebJi® does not publish a Next.js RAM price. The build is the memory spike, and the Node process stays resident after it. A sample VPS-Start on the pricing page is 2 vCPU and 4 GB RAM, and the monthly figure is quoted before payment.

Need help with this?

WebJi® support does it for you — free. Talk to our Jaipur team →