Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →The reliable self-hosting pattern is straightforward: build the application on the server with npm run build, run it with npm run start on a private localhost port, keep it alive with PM2 or systemd, and put Nginx in front to handle public HTTP and HTTPS traffic. Nginx terminates TLS and forwards requests to Next.js; the application port never needs to be exposed to the internet.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
This guide covers a production deployment on a Linux VPS, including DNS, server hardening, environment variables, process supervision, reverse-proxy configuration, TLS, verification, updates, and the operational details that matter for image optimization, streaming, and multiple instances.
As an Amazon Associate I earn from qualifying purchases.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchUnderstand the production architecture
A VPS deployment normally has four layers. The public DNS name points to the VPS address. Nginx listens on ports 80 and 443, handles TLS and request filtering, and proxies traffic to Next.js on a loopback address such as 127.0.0.1:3000. The Next.js process serves the production build, while PM2 or systemd restarts it after a crash and starts it again after a reboot.
browser
|
| HTTPS :443
v
Nginx (TLS, limits, proxy)
|
| http://127.0.0.1:3000
v
Next.js production server
|
v
application code, cache, and storage
This arrangement is safer than binding Next.js directly to a public interface. Next.js documentation recommends a reverse proxy because it can absorb malformed requests, slow-connection attacks, payload limits, rate limiting, and related request concerns before they reach the application.
#1 Best Overall
- BLUE LIGHT BLOCKING GLASSES: Our blue light glasses for women boast UV400 protection, blocking harmful blue rays from computer screens. With these bluelight glasses women, you can enjoy gaming, reading, or watching TV with no worries of eye strain.
- EYE RELIEF: Our blue light glasses are engineered to reduce blurry vision or strain caused by prolonged screen time. These womens blue light glasses aid in better sleep by preventing blue light from disrupting your natural sleep cycle, helping you fall asleep faster and enjoy a more restful night's sleep, making them the perfect christmas present.
- COMFORTABLE: Crafted from durable material, our trendy blue light glasses for woman or blue light glasses men ensure long-lasting comfort. The high-transmittance lenses accessories, gamer gifts for men, help keep your eyes relaxed. Perfect stocking stuffers, gifts for gamers men, christmas gifts for men, halloween costumes.
- LIGHTWEIGHT: These clear blue light glasses feature a lightweight frame, meaning they’ll stay comfy for long-term wear. Perfect as blue blockers glasses for women or mens blue light glasses, these non-prescription fake glasses for men can be worn throughout the day. The blue light blocking glasses women feature polycarbonate HD lenses, which are anti-reflective and restore true color.
- WORRY-FREE PURCHASE: If you experience any issues, our support team is ready to assist you quickly. These are the perfect costume glasses for cosplay dressing up.
Choose how Next.js will run
Decide the runtime model before provisioning the server. The choice affects feature support, deployment files, cache handling, and how you perform updates.
| Deployment model | Feature coverage | Operational complexity | Proxy requirement | Cache and storage considerations | Best fit |
|---|---|---|---|---|---|
| Node.js server | Supports all Next.js features | Lowest for a conventional VPS; install Node.js, the package manager, a supervisor, and Nginx | Use a reverse proxy rather than exposing the application port | A single process can use local cache and disk, but multiple processes require deliberate shared-cache and durable-storage decisions | Dynamic rendering, Route Handlers, Server Actions, streaming, image optimization, and other server behavior |
| Docker | Supports all Next.js features | Higher initial setup, but repeatable images and releases simplify operations | Normally place Nginx or another proxy in front of the container | Container filesystems are replaceable; mount persistent volumes or use external services for data that must survive a replacement | Teams that want immutable releases, consistent local/CI production environments, or several services on one VPS |
| Static export | Limited feature set; no server-only behavior | Simple: generate files and serve them from Nginx or Apache | Nginx or another web server can serve the files directly | Assets are ordinary files; there is no Next.js server cache or runtime filesystem | Sites whose pages and client-side code work without dynamic server rendering or server APIs |
When the Node.js server is the right choice
The Node.js path is the default for a dynamic VPS deployment. The project must expose build and start scripts, and the production sequence is npm run build followed by npm run start. This path keeps the full Next.js feature set available.
When Docker is worth the extra layer
Docker also supports all Next.js features and packages the runtime, dependencies, and application into a repeatable image. For a minimal production image, use Next.js’s official standalone-output pattern. You still need to decide where uploads, generated files, caches, and databases live; rebuilding a container must not delete data that the application needs.
When static export is sufficient
Static export can be served by a plain Nginx or Apache installation, but it cannot perform server-only behavior. Do not select it if the application relies on dynamic server-rendered routes, Route Handlers, Server Actions, runtime authentication checks, or other features that need a Node.js process.
Prepare the VPS and DNS
Provision a supported Linux image
Choose a maintained Linux distribution and an architecture supported by the Node.js version required by the project. Record the VPS public IPv4 address and, if you will use IPv6, its IPv6 address as well. The exact CPU, memory, disk, region, backups, and bandwidth depend on your application and provider; no universal VPS size guarantees a particular Next.js workload.
Point the hostname at the server
- Create an A record for the production hostname, such as
app.example.com, pointing to the VPS IPv4 address. - Create an AAAA record only when the VPS and firewall are configured for IPv6.
- Wait for DNS propagation, then verify from a workstation with
dig app.example.comor an equivalent DNS lookup.
Use the hostname you intend to place in the TLS certificate. If you are migrating an existing site, lower the old DNS record’s TTL ahead of the change and keep the previous server available until the new deployment is verified.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsHarden the Linux server before deploying
Use a non-root account for routine work. The following commands assume a Debian- or Ubuntu-style distribution and an initial root login; adjust package commands for another distribution.
apt update
apt full-upgrade -y
apt install -y ca-certificates curl git build-essential ufw
adduser deploy
usermod -aG sudo deploy
Copy your SSH public key to the deploy account, then open a second terminal and confirm that key-based login works before changing SSH settings:
ssh-copy-id [email protected]
ssh [email protected]
The address above is an example documentation address. Use the real VPS address for your server. Once the second session is confirmed, configure the firewall:
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status verbose
At this stage, allow SSH only. Add HTTP and HTTPS after Nginx is installed:
Rank #2
- WINDEX GAMING WIPES: effortlessly clean all your gaming gear and gaming electronics in one easy step with our new Windex Gaming Wipes
- AMMONIA FREE: our ammonia-free formula is safe to use on all of your favorite gaming equipment like consoles, headsets, controllers, screens, keyboards, and more
- PRE-MOISTENED WIPES: each wipe instantly removes dust, dirt, and stubborn smudges and fingerprints leaving a streak-free shine
- ANTI-STATIC: great for cleaning and wiping down your gaming gear and electronics leaving behind no visible residue
- COMPACT RESEALABLE PACKAGE: store your pack of Windex Gaming Wipes anywhere in your home for whenever a quick and easy wipedown is needed
sudo ufw allow 'Nginx Full'
sudo ufw status numbered
For a hardened installation, edit the SSH daemon configuration to disable direct root login and password authentication after confirming that key access works. Keep the current session open, test a new session, and only then reload the daemon. A mistake in SSH configuration can lock you out, so use the VPS provider’s console recovery access as a fallback.
Install a compatible Node.js runtime
Read the project’s package.json and the documentation for its Next.js release to determine the supported Node.js range. Compatibility is a project requirement, not a value to guess from the VPS distribution. Install a Node.js release in that range using the distribution packages or an approved Node.js version manager, then verify the result:
node --version
npm --version
If the distribution’s package is older than the project’s requirement, install a compatible current release through a maintained version manager or repository, then run the checks again. Keep the same major Node.js version in your deployment, CI, and local development environments when possible; changing it during a release can expose native-module or lockfile differences.
Install Git and compilation tools even when the application is mostly JavaScript. Some dependencies contain native components and need a compiler during installation.
Recommended Free Tools
Create the application directory and install dependencies
Place the application outside a user’s home directory with ownership assigned to the deployment account. One common layout is /var/www/next-app.
sudo mkdir -p /var/www/next-app
sudo chown -R deploy:deploy /var/www/next-app
cd /var/www/next-app
Clone the repository or upload the release files using your normal secure delivery method. For a Git checkout, set the repository address in your shell and clone it into the directory:
export REPOSITORY_URL='your-repository-address'
git clone "$REPOSITORY_URL" /var/www/next-app
Use the lockfile that belongs to the project. Install dependencies with the matching package manager:
cd /var/www/next-app
npm ci
npm ci is appropriate when the repository contains a valid package-lock.json and gives a reproducible install. If the project uses another package manager, run its frozen-lockfile equivalent instead of mixing tools. Do not delete a lockfile on the server to make an installation pass; fix dependency or Node.js compatibility in source control and deploy the corrected lockfile.
Free tools Windows power users keep installed
One-click scans. No signup required.
Configure environment variables safely
Separate values needed while building from values read only by server code. Next.js embeds variables whose names begin with NEXT_PUBLIC_ into the browser bundle during next build. Anyone who downloads the JavaScript can read those values, so never put passwords, private keys, database credentials, or signing secrets behind that prefix.
Build-time values
Set public API base URLs, feature flags, and other values that are intentionally visible before running the production build. If one of these values changes, rebuild the application; changing the file after the build does not rewrite an already generated browser bundle.
Rank #3
- Ergonomic & Adjustable Design: Fight "text neck" and improve your posture. Designed for comfort, it offers an adjustable height (7.1in-8.5in) (1.4in adjustable range) and angle (5°-85°) Please note: cell phone stand is only 9 inches tall—the length of a standard pencil
- Without blocking subtitles Perfect for office desk Tiktok Face Time Zoom video—this is the ultimate kitchen desk essential for phones! Perfect viewing experience while reducing neck back strain, A must-have for gamers streamers desk, and anyone who values both style and support!
- Sleek & Stable Design fits Otterbox Case: Say goodbye to bent cables, tangles, and tip-overs! LISEN’s stylish adjustable desk phone holder features a built-in charging hole and smart cable management, keeping your phone secure and your workspace clutter-free cool gadgets for men
- ANTI-SLIP DESIGN free hands: The under 10.00 items easy gadgets back and the bottom of this kitchen essentials for women are fully covered by anti-skid silicone, which LISEN stand up desk decor can provide maximum protection device from any scratches and slides
- Your Perfect Viewing Companion:If your product arrives damaged or breaks within 365 days, reach out to LISEN for a quick and hassle-free solution. Struggling with assembly, like tightening the screw? We’ve got your back! Your experience matters to us. (Product including: phone Holder stand*1, screw*1, hexagon screwdriver*1, specification*1)
Runtime server-only values
Keep private values in server-only environment variables and read them from server components, Route Handlers, or other server code. Store the file outside version control and restrict its permissions:
sudo install -o deploy -g deploy -m 600 /dev/null /var/www/next-app/.env.production
sudo -u deploy nano /var/www/next-app/.env.production
Do not commit .env.production or copy it into a public directory. Confirm that the repository’s ignore rules cover local environment files. A process supervisor can also provide environment values, but the same public-versus-private rule still applies.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Load the values for the build
Next.js automatically reads the appropriate environment files from the project directory. Before building, check that the file is present, owned by the deployment user, and contains the intended production values. Never print the complete file into deployment logs. If your application uses shell exports instead, export them in the same shell that runs the build and the process supervisor.
Build and test the production server locally
Run the production build as the deployment user:
cd /var/www/next-app
npm run build
The build generates the optimized production output and fails when required code, dependencies, or build-time variables are missing. Fix build errors before configuring Nginx; a proxy cannot make an incomplete build work.
Start Next.js on a private port and bind it to localhost:
PORT=3000 HOSTNAME=127.0.0.1 npm run start
In another SSH session on the VPS, test the local endpoint:
curl -I http://127.0.0.1:3000
Stop the foreground process after the local response is correct. The public hostname should not be used for this first test because DNS and Nginx have not been configured yet.
Keep Next.js running with PM2 or systemd
PM2 deployment
PM2 is a convenient process supervisor for a single VPS. Install it globally using the compatible Node.js installation, then start the existing npm run start script:
sudo npm install --global pm2
cd /var/www/next-app
pm2 start npm --name next-app -- start
Set the port in the PM2 environment if the application does not already define it. A simple ecosystem file makes the setting explicit and keeps deployment configuration in one place:
module.exports = {
apps: [{
name: 'next-app',
cwd: '/var/www/next-app',
script: 'npm',
args: 'run start',
env: {
NODE_ENV: 'production',
PORT: 3000,
HOSTNAME: '127.0.0.1'
}
}]
};
Save that file as ecosystem.config.js, then use:
pm2 delete next-app
pm2 start ecosystem.config.js
pm2 status
pm2 logs next-app
Register PM2 with the system startup process and save the current process list:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #4
- Easy Installation: Our gaming lights have been designed to enhance your entertainment experience. Simply position the led light bar next to your TV or game console to create a game room environment with ease. They come with USB power and a 60 inch cord for direct mounting and mobility
- Audio Syncing & Extensive Mode: The built-in high-sensitivity music sensor allows you to sync the TV led lights to your favorite music. Lights react and move to the beat of music, film and game audio, creating an incredible immersive sound and light experience – and all without the need for an additional hub. You can choose from 64+ patterns, including strobe, illusion, jump, energy, gradient, running, chasing, fluttering mode etc. Each mode can be applied to different scenes
- 64+ Chasing IC+RGB & W Effect: The independent control design of IC+RGB and white all-in-one multifunctional rgbw led bar lights monitor backlight allows you to easily switch the led lights for desk between IC+RGB and white to enjoy a variety of lighting effects, you can choose white lighting mode with high brightness for better illumination when working, etc. Choose IC+RGB lighting mode when you need to create an entertaining atmosphere for the light show, 16 million colours of Color changing rgb light bar let you dance to the beat and create a dynamic party atmosphere
- Dynamic and Dimmable Lights: 1%-full brightness free brightness adjustment gives you the flexibility to adjust dimmable led light bar for room decorations or a variety of occasions
- USB Powered: USB light bars for room can be powered by powernank, usb charger, TV, Monitor, laptop PC mainframe, making behind TV led lighting bar easy to install in any location.TV led lights are powered by the TV usb interface / PC mainframe, can be turned on/off synchronously with TV / PC
pm2 startup
pm2 save
The pm2 startup command prints a second command containing the account and startup path. Run that printed command with the required privileges, then run pm2 save again. Test both a controlled restart and a reboot during a maintenance window.
systemd deployment
systemd is a built-in alternative with no additional Node.js package. Create a unit such as /etc/systemd/system/next-app.service:
[Unit]
Description=Next.js production server
After=network.target
[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/var/www/next-app
Environment=NODE_ENV=production
Environment=PORT=3000
Environment=HOSTNAME=127.0.0.1
ExecStart=/usr/bin/npm run start
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Check the actual path returned by command -v npm; version managers often place npm somewhere other than /usr/bin/npm. Adjust ExecStart accordingly. Then load and enable the unit:
sudo systemctl daemon-reload
sudo systemctl enable --now next-app
sudo systemctl status next-app
sudo journalctl -u next-app -n 100 --no-pager
Choose one supervisor for the production process rather than running PM2 and systemd against the same application. Both can restart a process; running both creates confusing duplicate instances and port conflicts.
Install Nginx as the reverse proxy
Install Nginx and create a site configuration for the hostname. The example forwards every request to the private Next.js listener and passes the original host and client information:
sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/next-app
server {
listen 80;
listen [::]:80;
server_name app.example.com;
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";
}
}
Enable the site, remove the default site if it would catch the hostname, validate the configuration, and reload Nginx:
sudo ln -s /etc/nginx/sites-available/next-app /etc/nginx/sites-enabled/next-app
sudo nginx -t
sudo systemctl reload nginx
Open port 80 and 443 in the firewall when Nginx is ready:
sudo ufw allow 'Nginx Full'
The command above should be entered without the stray newline character shown in some copied terminals; the intended command is:
sudo ufw allow 'Nginx Full'
Keep port 3000 closed externally. Nginx is the only public entry point, so it can enforce request limits and TLS policy consistently.
Proxy headers and WebSocket-style upgrades
The upgrade headers in the example are harmless for ordinary HTTP traffic and preserve protocols that need connection upgrades. The forwarded protocol header lets application code distinguish the original HTTPS request from the internal HTTP hop. If your application constructs absolute URLs, verify that it trusts the proxy arrangement correctly.
Best Value
- Compatible with Wide Screens - To ensure compatibility with the dual monitor mount, your each monitor must meet three conditions at the same time: First, computer screens size range: 13 to 32 inches. Second, screen weight range: 4.4 to 19.8 lbs. Third, the back of the monitor screen must have VESA mounting holes with a pitch of 75x75mm or 100x100mm.
- Regarding the compatibility with desks - Your desk must meet three conditions at the same time: First, desk material: Only wooden desks are recommended, plastic or glass desks cannot be used. Second, desk thickness range: 0.59" - 3.54". Third, the bottom of the desk should not have any cross beams or panels, as this will interfere with installation. We recommend carefully checking that your desk and monitors meets all above conditions before purchasing.
- Dual C-Clamp Hold - Worried your dual monitors might wobble or slip? Our upgraded base uses a larger platform plus a dual C-clamp structure to lock the dual monitor arm firmly to your desk. Each arm safely keeps your screens steady while you type, click and game—no shaking, no sliding, just a clean and secure setup you can trust every day. It also provides Grommet Mounting installation choice, both options ensure stable and secure fixation for your 0.59" - 3.54" desk.
- Full-Motion Adjustment For Comfortable View - Pull the screen closer when you’re deep in a spreadsheet, push it back to watch videos, or rotate to portrait for coding — moving everything smoothly with just one hand. The monitor stand offers +85°/-50° tilt, ±90° swivel and 360° rotation. Raise your monitor up to 15.75″ to support a healthy sitting posture. Whether you’re working from home, gaming through the night, or switching between video calls and documents, getting the screens to your natural line of sight helps relieve neck, shoulder and back strain so you can stay focused longer with less fatigue.
- Keep Your Desk Organized: By lifting both screens off the desktop, this dual monitor stand opens up valuable space for your keyboard, notebook, docking station or a simple, clutter-free work area. Built-in cable management guides wires along the arms, keeping cords out of sight and out of the way. Enjoy a tidy, modern workstation that looks as good as it feels to use.
Streaming and Suspense
Streaming responses must not be buffered until the entire response is complete. Disable Nginx response buffering for routes that stream, for example with proxy_buffering off;, and have the application send X-Accel-Buffering: no where appropriate. Confirm that every intermediary between the client and Nginx also passes chunked or HTTP/2 streaming. A CDN, load balancer, or security gateway that buffers responses can defeat streaming even when Nginx is configured correctly.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Add HTTPS and redirect HTTP
Use a certificate authority client appropriate for your Linux distribution and Nginx. A common Debian/Ubuntu sequence is:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d app.example.com
Follow the prompts to request the certificate and install the Nginx HTTPS configuration. The client can create an HTTP-to-HTTPS redirect. Confirm renewal is scheduled by the package and test the renewal path with the client’s dry-run option. After TLS is enabled, verify that the application receives X-Forwarded-Proto: https and that cookies marked Secure behave as expected.
Verify the deployment before calling it live
Work through the checks below from both the VPS and an external network:
- DNS resolves the intended hostname to the VPS address.
systemctl status nginxreports an active service andnginx -tpasses after every configuration change.- The supervisor reports one healthy Next.js process and its logs show no restart loop.
curl http://127.0.0.1:3000succeeds on the VPS while port 3000 is unreachable from the public internet.- The HTTPS hostname returns the expected page, redirects HTTP, and presents a valid certificate for the hostname.
- Static JavaScript, CSS, fonts, and images load without 404 responses.
- Dynamic routes, form submissions, authentication, API handlers, and error pages behave as they did in local production mode.
- Production environment values are present where server code needs them, while secrets are absent from browser responses and logs.
- A controlled process restart restores the site, and a VPS reboot brings the supervisor and Nginx back automatically.
- Image-heavy pages and streaming routes are tested under realistic traffic rather than only with a basic HTML request.
Inspect logs at each layer when a check fails:
pm2 logs next-app
sudo journalctl -u next-app -f
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log
Handle Next.js image optimization correctly
next/image works in a self-hosted deployment with zero configuration when the application is served by next start. Image optimization still consumes CPU and memory. On glibc-based Linux systems, monitor memory use and apply the configuration guidance appropriate to your Next.js release if optimization causes excessive consumption. Do not assume that a successful HTML request proves image processing is healthy; request representative image sizes and inspect the process while they are being generated.
If you use a custom image loader or an external image service, validate allowed remote patterns and cache headers separately. Keep generated image data on durable storage only when the application requires it; otherwise, a local cache can be rebuilt after a restart.
Plan for cache, storage, and multiple instances
A single VPS process often hides assumptions that become visible when you add a second process or server. Local in-memory state, filesystem uploads, and a process-local cache are not automatically shared. Before running multiple instances, decide where each category of data belongs:
- Use a shared cache or a cache service when all instances must see the same cached result.
- Use durable shared storage or object storage for uploads and generated files that must survive replacement of a process or server.
- Use a database or another shared data store for user and application state; do not rely on one process's memory.
- Confirm whether session handling requires sticky routing or a shared session store.
The reverse proxy can distribute requests, but it cannot create distributed cache coordination or durable storage. Treat those as explicit architecture decisions before scaling beyond one process.
Deploy updates without avoidable downtime
Safe update sequence
- Keep the current release and its environment file available until the new build has passed local checks.
- Fetch the intended commit or release into the application directory and verify the lockfile.
- Install dependencies with the project's frozen or reproducible command.
- Run
npm run buildas the deployment user and stop if it fails. - Restart the one supervisor-managed process, then inspect its status and logs.
- Request the public hostname, key dynamic routes, static assets, image URLs, and streaming endpoints.
- Keep the previous release available for rollback until verification is complete.
With PM2, a straightforward restart is:
pm2 restart next-app
pm2 status
pm2 logs next-app --lines 100
With systemd, use:
sudo systemctl restart next-app
sudo systemctl status next-app
sudo journalctl -u next-app -n 100 --no-pager
Rollback triggers
Roll back when the build is incomplete, the process repeatedly exits, server-only environment variables are missing, static assets return 404 responses, or a critical route fails. Restore the previous code and lockfile, reinstall only if dependencies changed, rebuild, and restart the supervisor. Keep database migrations backward-compatible when a release may need to be reverted.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Troubleshoot common failures
| Symptom | Likely cause | Checks and fix |
|---|---|---|
| 502 Bad Gateway from Nginx | Next.js is stopped, listening on another port, or bound to a different address | Check the supervisor status and logs, run ss -ltnp, curl 127.0.0.1:3000, and make the Nginx upstream match the actual listener |
| Nginx shows the default page | The site is not enabled or the hostname does not match server_name |
Check the symlink in /etc/nginx/sites-enabled, run nginx -t, and verify DNS and the Host header |
| Build fails with a missing variable | A build-time value was absent or the environment file was unreadable | Check ownership and permissions, set the required value before npm run build, and rebuild; do not expose a secret by adding a public prefix |
| Browser code contains a secret | The variable name began with NEXT_PUBLIC_ or the secret was hard-coded |
Rotate the exposed credential, remove it from client code, move it to a server-only variable, and rebuild every affected bundle |
| Changes to an environment value have no effect | The value was embedded during the previous build or the process was not restarted | Rebuild for public variables; restart the supervisor for runtime server variables; verify the running process environment without printing secrets |
| Static assets return 404 | The build directory and running code are from different releases, or Nginx is routing incorrectly | Inspect the current working directory, rebuild the checked-out commit, and check browser network errors and Nginx access logs |
| Streaming arrives all at once | Nginx or another intermediary is buffering the response | Disable proxy buffering for the streaming route, send X-Accel-Buffering: no, and test each intermediary's HTTP/2 or chunked-response behavior |
| Images cause memory pressure | On-the-fly optimization is expensive for the VPS workload | Measure the process while requesting representative images, apply the glibc/Linux optimization guidance for the Next.js release, or move image processing to a suitable service |
| Application works locally but not after reboot | PM2 startup was not registered, pm2 save was omitted, or the systemd unit has an incorrect Node path |
Test the startup registration, inspect the unit or PM2 startup output, and verify the service as the deployment user |
| Only some users see stale data | Instances use separate local caches or storage | Adopt shared cache and durable storage, or keep a single process until the application is designed for distributed operation |
Operational security and maintenance checklist
- Apply operating-system security updates on a regular schedule and reboot when required.
- Use SSH keys, a non-root deployment account, and a tested recovery-console path.
- Allow only required firewall ports: SSH, HTTP, and HTTPS.
- Keep the Next.js listener on localhost or another private interface.
- Protect environment files with restrictive ownership and permissions, and rotate credentials after accidental exposure.
- Review Nginx access and error logs for unusual request patterns and failed upstream connections.
- Back up application data, databases, and any persistent uploads separately from the VPS itself.
- Test certificate renewal, process restart, reboot recovery, and rollback before an incident occurs.
- Record the Node.js version, package-manager version, lockfile, environment schema, and release commit for each deployment.
Final deployment decision
For most dynamic Next.js applications on a Linux VPS, use the Node.js server model: build with npm run build, serve with npm run start on localhost, supervise with exactly one of PM2 or systemd, and proxy through Nginx with HTTPS. Choose Docker when repeatable immutable packaging is more valuable than a simpler host installation. Choose static export only when the application genuinely does not need a Next.js server. Treat environment-variable visibility, proxy buffering, image memory use, and shared cache or storage as production concerns rather than afterthoughts.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




