---
title: "How to host Next.js on a VPS with PM2, Nginx and HTTPS | StreetHosting"
description: "Host Next.js on a VPS: build with next start or standalone, PM2 restart on boot, Nginx with streaming, domain, HTTPS and deploys that keep the site up."
url: "https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps"
type: "page"
language: "en-US"
---

VPS · 9 min · Intermediate

Published on Sep 28, 2026 · Updated on Sep 28, 2026

# Next.js in production on your VPS, from build to HTTPS

Next.js runs in full on a VPS with Node, including server rendering, ISR and Server Actions. Learn how to build it, keep the process alive with PM2, put Nginx in front and update without breaking the site.

By [Equipe StreetHosting](https://streethosting.com.br/en/autores#equipe-streethosting) · StreetHosting infrastructure and support team

[Deploying and running apps](https://streethosting.com.br/en/guides/topics/deploy) [Network, DNS and domains](https://streethosting.com.br/en/guides/topics/networking) [Certificates and HTTPS](https://streethosting.com.br/en/guides/topics/ssl)

Summarize with:

[](https://chat.openai.com/?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "ChatGPT") [](https://claude.ai/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Claude") [](https://www.google.com/search?udm=50&aep=11&q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Google AI Mode") [](https://x.com/i/grok?text=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Grok") [](https://www.perplexity.ai/search/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Perplexity")

Share:

[](https://x.com/intent/tweet?text=How%20to%20host%20Next.js%20on%20a%20VPS%20with%20PM2%2C%20Nginx%20and%20HTTPS&url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps "Share on X") [](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps "Share on Facebook") [](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps "Share on LinkedIn") [](https://wa.me/?text=How%20to%20host%20Next.js%20on%20a%20VPS%20with%20PM2%2C%20Nginx%20and%20HTTPS%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fhost-nextjs-on-vps "Share on WhatsApp")

For agents: Copy as Markdown [.md](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps.md)

In this guide 8 sections

* [next start, standalone or export](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#escolher-modo)
* [Preparing the VPS](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#preparar-vps)
* [Build and environment variables](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#build)
* [Running with PM2](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#pm2)
* [Nginx, domain and HTTPS](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#nginx-https)
* [Updating without taking the site down](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#atualizar)
* [Common errors](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#erros-comuns)
* [Which VPS to choose](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#onde-rodar)

Quick answer

To **host Next.js on a VPS**, install Node.js LTS, run `npm ci` and `npm run build`, bring the application up with PM2 listening only on 127.0.0.1:3000 and put Nginx in front with HTTPS from Let's Encrypt. Enable restart on boot with `pm2 startup` and turn off Nginx buffering so streaming works.

## next start, standalone or export: which one to use[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#escolher-modo)

Before installing anything, decide how the site will run. Next.js has three production outputs, and the choice changes what needs to exist on the VPS.

| Mode              | How it runs                                        | Advantage                                | When to use it                                                     |
| ----------------- | -------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------ |
| next start        | Node process with the project's full node\_modules | Simplest, same as the local environment  | Build done on the VPS itself                                       |
| output standalone | node server.js with only the traced dependencies   | Lean folder, starts without npm install  | Build in CI or Docker, deploy by copying files                     |
| output export     | Static HTML served directly by Nginx               | No Node in production, minimal footprint | Site with no server rendering, no API routes and no Server Actions |

This guide covers the first two, which keep every feature of the framework. The Node, PM2 and Nginx base is the same as for any Node application, covered in detail in the guide on [hosting Node.js on a VPS](https://streethosting.com.br/en/guides/vps/host-nodejs-on-vps); here the focus is on what is specific to Next.js: a heavy build, variables baked into the JavaScript, static files and streaming.

Static export deserves a look before you rule it out. Landing pages, documentation and blogs with no per-user content are cheaper and faster served as plain HTML by Nginx, with no Node process to keep alive. The trade-off is losing everything that depends on a server: API routes, Server Actions, ISR, cookies read during rendering and image optimization without an external loader.

## Preparing the VPS: Node.js LTS and PM2[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#preparar-vps)

Next.js 16 requires Node.js 20.9 or newer, but the 20 line is already out of support. Use the active LTS, Node.js 24, installed from the NodeSource repository. That way the binary lands in `/usr/bin/node` and PM2 finds the same Node at boot, with no path surprises.

`curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - sudo apt install -y nodejs git node -v sudo npm install -g pm2 sudo mkdir -p /var/www/meu-site sudo chown $USER:$USER /var/www/meu-site`

Run everything as a regular user with sudo, never as root. The folder under `/var/www` avoids an Ubuntu 24.04 gotcha: home directories under `/home` ship closed to other users, and Nginx would not be able to read files from there if you ever want to serve static files straight from disk.

`next build` uses far more memory than the running site. On a 2 GB VPS, create swap before the first build, following the guide on [swap on Ubuntu](https://streethosting.com.br/en/guides/vps/set-up-swap-ubuntu-vps), or the process dies midway with no clear message.

## Build and environment variables[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#build)

Organize the folder in three parts from the very first deploy: `releases` holds every built version, `shared` holds what does not change between versions (the environment file) and `current` is a symbolic link to the version that is live. It looks like overkill now, but this structure is what lets you update without taking the site down later on.

`cd /var/www/meu-site mkdir -p releases shared nano shared/.env.production chmod 600 shared/.env.production git clone https://github.com/sua-conta/meu-site.git releases/v1 cp shared/.env.production releases/v1/ cd releases/v1 npm ci npm run build ln -sfn /var/www/meu-site/releases/v1 /var/www/meu-site/current`

`npm ci` installs the dependencies exactly as they are in the lockfile, without updating anything on its own, which keeps production from running different versions than the ones you tested.

The detail that trips up most people coming from managed hosting is the variables. By default, environment variables exist only on the server. The ones starting with `NEXT_PUBLIC_` are copied into the browser JavaScript during the build. The result: changing one of them in the file and restarting changes nothing; you have to run the build again. Pages generated statically at build time also freeze the values read at that moment.

### Standalone mode[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#standalone)

For standalone mode, enable the option in the config file:

`// next.config.ts import type { NextConfig } from "next"; const nextConfig: NextConfig = { output: "standalone", }; export default nextConfig;`

The build creates `.next/standalone` with a `server.js` and only the packages the code actually uses. The `public` and `.next/static` folders are not copied by default; without them the site loads with no CSS, no JavaScript and no images. Copy them after every build:

`cp -r public .next/standalone/ cp -r .next/static .next/standalone/.next/`

If the build happens in CI, use a Linux x64 runner, same as the VPS. The standalone folder carries native binaries, such as the sharp used for image optimization, and a build made on Windows or macOS copies the wrong binary.

## Running with PM2 and restart on boot[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#pm2)

PM2 keeps the process alive, restarts it if it crashes and brings it back up after a reboot. Create the config file in `/var/www/meu-site`, outside the versions, pointing at the `current` link. For `next start`:

`// /var/www/meu-site/ecosystem.config.js module.exports = { apps: [ { name: "meu-site", cwd: "/var/www/meu-site/current", script: "node_modules/next/dist/bin/next", args: "start -H 127.0.0.1 -p 3000", instances: 1, exec_mode: "fork", max_memory_restart: "700M", env: { NODE_ENV: "production" }, }, ], };`

In standalone mode, the process is `server.js` itself, which reads the port and address from the `PORT` and `HOSTNAME` variables. Pass the runtime variables the application uses as well:

`{ name: "meu-site", cwd: "/var/www/meu-site/current/.next/standalone", script: "server.js", env: { NODE_ENV: "production", PORT: "3000", HOSTNAME: "127.0.0.1", DATABASE_URL: "postgresql://app:senha@127.0.0.1:5432/app", }, }`

Start it, save the process list and generate the boot service:

`cd /var/www/meu-site pm2 start ecosystem.config.js pm2 save pm2 startup systemd # copy and run the sudo line the command above prints curl -I http://127.0.0.1:3000`

Listening on 127.0.0.1 is deliberate: port 3000 is unreachable from outside and all traffic goes through Nginx. The differences between PM2 and a plain systemd service are in the guide on [PM2 and systemd on a VPS](https://streethosting.com.br/en/guides/vps/pm2-vs-systemd-nodejs).

PM2 logs grow without limit by default. Install the rotation module once and forget about it: `pm2 install pm2-logrotate`. To follow errors in real time, use `pm2 logs meu-site`.

Start with one instance. PM2 cluster mode works, but each process keeps its own in-memory cache, and ISR or tag-based revalidations may not reach all of them at the same time. If you need more processes, read the multiple instances section of the Next.js self-hosting documentation first.

## Nginx, domain and HTTPS[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#nginx-https)

Point the domain at the VPS IP with one A record for the domain and another for www, as explained in the guide on [DNS for a VPS](https://streethosting.com.br/en/guides/vps/point-domain-to-vps). Then install Nginx and create the site:

`sudo apt install -y nginx sudo nano /etc/nginx/sites-available/meu-site`

`server { listen 80; listen [::]:80; server_name seu-dominio.com.br www.seu-dominio.com.br; client_max_body_size 10m; location / { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; } }`

* **Forwarded headers:** Next.js uses the original Host and protocol to build URLs and validate the origin of Server Actions. Without them, forms can fail behind the proxy.
* **proxy\_buffering off:** the App Router sends the page in chunks (loading and Suspense). With buffering on, Nginx holds everything and delivers it all at once, defeating streaming.
* **client\_max\_body\_size:** the Nginx default is 1 MB. Raise it if the site accepts uploads.

Enable the site, open the firewall and issue the certificate:

`sudo ln -s /etc/nginx/sites-available/meu-site /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t && sudo systemctl reload nginx sudo ufw allow OpenSSH sudo ufw allow 'Nginx Full' sudo ufw enable sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d seu-dominio.com.br -d www.seu-dominio.com.br sudo certbot renew --dry-run`

Certbot edits the Nginx block, creates the HTTP to HTTPS redirect and schedules automatic renewal through the systemd timer. Security headers and troubleshooting of failed issuance are in the guide on [SSL certificates with Let's Encrypt and Nginx](https://streethosting.com.br/en/guides/vps/lets-encrypt-ssl-certificate-vps).

### What about caching static files?[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#cache-estaticos)

Nothing to configure in Nginx. Next.js already serves the files under `/_next/static`with a one-year public cache marked immutable, because each file name carries a hash of its content. Dynamic pages go out with a private cache, so one user's data is never stored for another. If you ever put a CDN in front, it picks up these same headers with no extra rule.

## Updating without taking the site down[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#atualizar)

The naive way to update is `git pull` followed by `npm run build` in the same folder. The problem: the build deletes and recreates the `.next` folder while the site is still running from it, and for minutes visitors get broken pages. The fix is to build each version in a separate folder and only switch a symbolic link once the build finishes.

`#!/usr/bin/env bash # /var/www/meu-site/deploy.sh set -euo pipefail APP=/var/www/meu-site RELEASE="$APP/releases/$(date +%Y%m%d%H%M%S)" git clone --depth 1 https://github.com/sua-conta/meu-site.git "$RELEASE" cp "$APP/shared/.env.production" "$RELEASE/" cd "$RELEASE" npm ci npm run build ln -sfn "$RELEASE" "$APP/current" pm2 startOrReload "$APP/ecosystem.config.js" --update-env # keep the five most recent versions for rollback ls -dt "$APP"/releases/* | tail -n +6 | xargs -r rm -rf`

It is the same sequence as the first deploy, just automated: the new version is built in another folder while the old one keeps serving, and the `current` link only changes when the build finishes without errors. If you are using standalone, add the two folder copies right after the build. Rolling back means pointing the link at the previous folder and reloading PM2. With a single instance in fork mode, the reload still leaves a gap of one or two seconds; the build, which is the slow part, no longer affects anyone.

This script is the starting point for automating with a pipeline. If you would rather have a panel handle the build, version switch and rollback for you, [Coolify](https://streethosting.com.br/en/guides/vps/install-coolify-on-vps) solves the same problem with containers.

## Common errors and how to fix them[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#erros-comuns)

| Symptom                                      | Likely cause                                 | How to fix it                                            |
| -------------------------------------------- | -------------------------------------------- | -------------------------------------------------------- |
| Build dies with Killed or heap out of memory | Not enough RAM at the build peak             | Create swap, build in CI or add RAM                      |
| Site with no CSS or JavaScript in standalone | public and .next/static were not copied      | Copy both folders after every build                      |
| NEXT\_PUBLIC\_ variable empty in the browser | It was not defined at build time             | Set it in the production file and run the build again    |
| 502 Bad Gateway                              | Process stopped or listening on another port | Check pm2 status and the process logs in PM2             |
| Page loads all at once                       | Nginx buffering holding back the stream      | Add proxy\_buffering off to the location block           |
| Failed to find Server Action after a deploy  | Browser still on the previous version's page | Reloading fixes it; set deploymentId to force the switch |
| Site down after rebooting the VPS            | pm2 save or pm2 startup were not run         | Run both and test with a reboot                          |

Image optimization from the Image component runs at request time and uses CPU. The result is cached on disk, so the first hit on each image is the most expensive. On pages with many photos, prefer files already at the right size so you do not burn processing for nothing.

## Which VPS to choose for Next.js[](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#onde-rodar)

Server rendering happens in the Node event loop, which uses one core per process. In practice, each page's response time depends heavily on per-core speed. That is why the [Ryzen 9 9950X VPS](https://streethosting.com.br/en/vps/ryzen), with up to 5.7 GHz and DDR5 memory, is the pick for sites with SSR. The second factor is build RAM, which sets the minimum plan when you compile on the VPS itself.

| Scenario                                                  | Suggested plan                        | Monthly price |
| --------------------------------------------------------- | ------------------------------------- | ------------- |
| Small site with the build done in CI                      | Ryzen 1 vCPU, 2 GB DDR5, 20 GB NVMe   | R$ 40.00      |
| Build on the VPS and SSR with moderate traffic            | Ryzen 2 vCPU, 4 GB DDR5, 40 GB NVMe   | R$ 66.00      |
| Several sites or a site with its database on the same VPS | Ryzen 4 vCPU, 8 GB DDR5, 80 GB NVMe   | R$ 118.00     |
| Store or portal with heavy traffic and cluster            | Ryzen 6 vCPU, 16 GB DDR5, 160 GB NVMe | R$ 222.00     |

The datacenter is in São Paulo, which shortens time to first byte for visitors in Brazil, and every VPS includes Anti-DDoS, root access and activation within 60 seconds. To compare with the Xeon line, which delivers more vCPU for the money at a lower clock, see the [VPS plans](https://streethosting.com.br/en/vps).

* Node.js 24 LTS installed from NodeSource
* Swap created if the VPS has 2 GB
* Application listening on 127.0.0.1:3000
* pm2 save and pm2 startup run
* Nginx with Forwarded headers and proxy\_buffering off
* Certificate issued and renewal tested with a dry run
* Deploys in separate folders with a symbolic link

In this guide

* [next start, standalone or export](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#escolher-modo)
* [Preparing the VPS](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#preparar-vps)
* [Build and environment variables](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#build)
* [Running with PM2](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#pm2)
* [Nginx, domain and HTTPS](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#nginx-https)
* [Updating without taking the site down](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#atualizar)
* [Common errors](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#erros-comuns)
* [Which VPS to choose](https://streethosting.com.br/en/guides/vps/host-nextjs-on-vps#onde-rodar)

## Frequently asked questions

Does Next.js run in full on a VPS?

It does. With next start, server rendering, ISR, Server Actions, image optimization and the proxy file all work with no extra configuration. What changes is that caching, scaling and updates become your responsibility.

Which Node.js version should I use with Next.js 16?

Next.js 16 requires at least Node.js 20.9, but the 20 line is already out of support. Use the active LTS, which as of September 2026 is Node.js 24, and keep the same major version on your development machine and on the VPS.

Do I need Nginx if Next.js is already a server?

It is what the official documentation recommends. Nginx terminates HTTPS, handles slow connections, limits request size and shields the Node process from malformed traffic, leaving Next.js free to render pages.

How much RAM does a Next.js build need?

It depends on the project, but builds of mid-sized projects often peak above 1 GB and can fail on a 2 GB VPS without swap. With 4 GB the build is comfortable; another way out is to build in CI and ship only the standalone folder.

Should I use next start or output standalone?

next start is simpler when the build happens on the VPS itself. Standalone produces a lean folder with server.js and only the required dependencies, ideal for builds in CI or Docker. Both deliver the same features in production.

Next step

See Ryzen VPS

Ryzen 9 9950X VPS in São Paulo with root access, NVMe and gamer Anti-DDoS.

[See Ryzen VPS](https://streethosting.com.br/en/vps/ryzen)

[See VPS plans Root VPS in Brazil with NVMe and Anti-DDoS.](https://streethosting.com.br/en/vps)

## Related guides

[VPS Intermediate How to host a Node.js app on a VPS in Brazil A Node.js app in production needs a process manager, a reverse proxy, HTTPS and automatic restarts. Follow the complete walkthrough on an Ubuntu VPS in São Paulo, close to your users and to Brazilian integrations. 9 min Read guide](https://streethosting.com.br/en/guides/vps/host-nodejs-on-vps) [VPS Intermediate PM2 vs systemd: keep your Node app always online on a VPS Your app needs to come back on its own after a crash and start together with the VPS. PM2 and systemd solve this in different ways. Here is how to set up each one and which to pick. 3 min Read guide](https://streethosting.com.br/en/guides/vps/pm2-vs-systemd-nodejs) [VPS Intermediate How to set up Nginx as a reverse proxy on a VPS Your app runs on an internal port and you want to serve it on a domain with HTTPS. Nginx as a reverse proxy solves that and also brings several apps together in one place. 3 min Read guide](https://streethosting.com.br/en/guides/vps/nginx-reverse-proxy-vps)

[← Back to the Guide Center](https://streethosting.com.br/en/guides)
