Next.js is a popular React framework supporting server-side rendering, static generation, and API routes — this guide covers deploying a Next.js application on a self-managed VPS.
Prerequisites
- Node.js installed (see How to Install Node.js on Ubuntu & Debian (with NVM))
Step 1 — Build Your Next.js Application
npm run build
Produces an optimized production build — run this either on your development machine (then transfer the build output) or directly on the server/in CI.
Step 2 — Transfer to Your Server (If Building Elsewhere)
rsync -avz --exclude node_modules . user@YOUR_SERVER_IP:/opt/myapp/
Step 3 — Install Production Dependencies on the Server
cd /opt/myapp
npm ci --production
Step 4 — Run with PM2 (Recommended Process Manager)
npm install -g pm2
pm2 start npm --name "nextjs-app" -- start
See Process Managers Compared: PM2 vs systemd vs Supervisor for why PM2 is a common choice specifically for Node.js applications like Next.js.
Step 5 — Configure PM2 to Start on Boot
pm2 startup
pm2 save
Step 6 — Configure Nginx as a Reverse Proxy
server {
listen 80;
server_name yourdomain.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 7 — Add HTTPS
sudo certbot --nginx -d yourdomain.com
Understanding Next.js Rendering Modes and Deployment Implications
Next.js supports static generation (pre-built HTML), server-side rendering (rendered per-request), and API routes — a self-hosted VPS deployment (via next start) supports all of these; some Next.js features are specifically optimized for certain hosting platforms, so verify full feature compatibility for self-hosted deployment if you're using advanced/newer Next.js features.
Static Export (If You Don't Need Server-Side Features)
next build && next export
If your application doesn't need server-side rendering or API routes, static export produces plain HTML/CSS/JS deployable via simple static hosting (see How to Host a Static Website on a VPS with Nginx) — simpler and often faster than running a full Node.js server.
Environment Variables
See Docker Compose .env Files and Environment Variables Explained and How to Manage Environment Variables and Secrets on a VPS — Next.js has specific conventions for environment variables exposed to the client (prefixed with NEXT_PUBLIC_) versus server-only variables; understand this distinction to avoid accidentally exposing sensitive values to client-side code.
Setting Up Zero-Downtime Deployments
pm2 reload nextjs-app
PM2's reload (rather than restart) attempts a more graceful transition, though genuinely zero-downtime deployment for a stateful Node.js process typically benefits from a load-balanced multi-instance setup for the most robust behavior.
Common Errors
Static assets (CSS/images) not loading correctly — verify Nginx correctly proxies all paths (not just the root), and check for any base path configuration mismatches between your Next.js config and deployment URL structure.
Continue Reading
- How to Deploy a Node.js Application with PM2 and Nginx
- Process Managers Compared: PM2 vs systemd vs Supervisor
- How to Host a Static Website on a VPS with Nginx
Browse more articles in Programming Languages & Runtimes.