How to Deploy a Next.js Application on a VPS

Next.js supports several deployment modes — fully static export, server-side rendering with Node.js, or a hybrid. This guide covers deploying a Node.js-rendered Next.js app on your own VPS.

Prerequisites

  • Node.js installed — see How to Install Node.js on Ubuntu & Debian (with NVM)
  • Nginx installed
  • Your Next.js application ready to deploy

Step 1 — Transfer and Build the Application

rsync -avz --exclude 'node_modules' --exclude '.next' ./myapp/ deploy@YOUR_SERVER_IP:/var/www/myapp/
cd /var/www/myapp
npm install
npm run build

Step 2 — Test the Production Server

npm run start

By default this runs on port 3000 — confirm it works, then stop it (Ctrl+C) to set up proper process management.

Step 3 — Run with PM2

pm2 start npm --name nextjs-app -- start
pm2 startup
pm2 save

Step 4 — Configure Nginx as a Reverse Proxy

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

Step 5 — Add HTTPS

sudo certbot --nginx -d myapp.example.com

Considering Static Export Instead (If Applicable)

If your Next.js app doesn't use server-side rendering features (API routes, dynamic SSR), a static export is simpler and more efficient to host:

next.config.js:
module.exports = {
  output: 'export',
};
npm run build

This produces static HTML in the out directory, servable directly with Nginx as described in How to Host a Static Website on a VPS with Nginx — no Node.js runtime needed in production at all.

Caching Next.js's Static Assets

location /_next/static/ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

Next.js's build output includes content-hashed filenames, making these safe to cache indefinitely — a new deployment automatically produces new filenames.

Deploying Updates

cd /var/www/myapp
git pull
npm install
npm run build
pm2 reload nextjs-app

Environment Variables

Next.js requires NEXT_PUBLIC_-prefixed variables to be available at build time for client-side use — ensure your .env.production file is correctly set before running npm run build. See How to Manage Environment Variables and Secrets on a VPS.

Common Errors

502 Bad Gateway — verify the Next.js process is actually running: pm2 status, and check logs with pm2 logs nextjs-app.

Environment variables not reflected in the client — client-visible variables must be set before npm run build, not just at runtime; rebuild after changing them.

Best Practices

  • Use static export when SSR features aren't needed — simpler and more resource-efficient
  • Cache the _next/static directory aggressively given its content-hashed filenames
  • Always rebuild after changing client-visible environment variables

Continue Reading

Browse more articles in Static Site Hosting & Frontend Deployment.

  • next.js deployment, next.js vps, react ssr deployment, pm2 nextjs
  • 0 أعضاء وجدوا هذه المقالة مفيدة
هل كانت المقالة مفيدة ؟

مقالات مشابهة

How to Host a Static Website on a VPS with Nginx

Static websites — plain HTML, CSS, and JavaScript with no server-side processing —...

How to Deploy a Static Site Built with Astro, Hugo, or Jekyll

Static site generators (Astro, Hugo, Jekyll) produce plain HTML/CSS/JS at build time —...

How to Optimize Images for Web Performance

Images are typically the largest contributor to page weight and load time. This guide covers...

How to Set Up a Jamstack Site with a Headless CMS Backend

The Jamstack architecture (JavaScript, APIs, Markup) combines a pre-built static frontend with a...

How to Configure Nginx for Single Page Applications (SPA Routing)

Single Page Applications (React, Vue, Angular) handle routing client-side in JavaScript —...