October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
VGSources
Blog

How to Host Multiple Node.js Apps on One VPS With Nginx

Run multiple Node.js applications on one VPS by giving each app a private port and using Nginx to route domains, terminate HTTPS, proxy WebSockets, and supervise reliable deployments.
Length10 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Host each Node.js application as its own process on a unique localhost port, then let Nginx be the only service exposed on ports 80 and 443. Nginx selects an application by hostname and proxies the request to the matching port—for example, app1.example.com to 127.0.0.1:3001, app2.example.com to 127.0.0.1:3002, and app3.example.com to 127.0.0.1:3003. Run every app under PM2 or systemd, terminate HTTPS at Nginx, and keep the Node.js ports private.

How the architecture works

A single VPS can serve many Node.js applications without giving each app a public IP address. The public edge is one Nginx installation listening on ports 80 and 443. Each Node.js app listens only on a different loopback port, and Nginx routes requests according to the requested hostname. The NGINX deployment guide documents this reverse-proxy pattern, including upstreams, proxy_pass, HTTPS blocks, and WebSocket locations: NGINX Node.js deployment guide.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Layer Example Purpose
DNS app1.example.com, app2.example.com Points every hostname to the VPS address.
Nginx Ports 80 and 443 Receives public HTTP/HTTPS traffic, selects a server block, and proxies it.
Application 1 127.0.0.1:3001 Private listener for the first Node.js app.
Application 2 127.0.0.1:3002 Private listener for the second app.
Application 3 127.0.0.1:3003 Private listener for the third app.
Supervisor PM2 or systemd Restarts failed processes and restores them after reboot.

This separation is important: Nginx handles network routing, while PM2 or systemd handles process lifecycle. A reverse proxy does not restart a crashed Node process, and a process supervisor does not decide which domain reaches which app.

Plan domains, ports, users, and directories first

Choose one hostname per application

Subdomains are the simplest arrangement because each hostname maps directly to one Nginx server block. For example:

#1 Best Overall
Sale
Gaoye Blue Light Blocking Glasses
  • 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.
  • app1.example.com → application directory /srv/app1 → port 3001
  • app2.example.com → application directory /srv/app2 → port 3002
  • api.example.com → application directory /srv/api → port 3003

Create an A or AAAA record for every hostname and point it to the VPS address before testing Nginx. DNS changes must resolve to the server before a hostname-based server block can be reached.

Assign a unique internal port

Write down a port map and keep it stable. Two applications cannot bind the same address and port. Configure each app’s environment so it listens on its assigned port and on the loopback interface where practical. A port such as 3001 is an internal convention, not a public endpoint; clients should use the domain over Nginx instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Isolate application files and identities

Place projects in separate directories and use a non-root service account for each app where practical. Separate accounts reduce the impact of a compromised application and make ownership, logs, and environment files easier to audit. Do not put secrets in a directory served as static web content.

Prepare the VPS

  1. Install a supported Node.js runtime for every application, Nginx, and either PM2 or systemd.
  2. Deploy each project into its own directory and install its production dependencies.
  3. Set environment variables, including the port each project should bind to.
  4. Start each app locally and verify that it responds on its assigned loopback port before introducing Nginx.
  5. Allow inbound traffic to ports 80 and 443. Keep application ports such as 3001–3003 bound to localhost or blocked by a private firewall rule.

Testing the applications directly first distinguishes application failures from proxy errors. A connection refused on 127.0.0.1:3002 means the second app is not listening; an Nginx 502 after the app is confirmed healthy usually points to the proxy target, permissions, or a port mismatch.

Configure one Nginx server block per hostname

Basic HTTP reverse-proxy block

Create a configuration for each hostname. The following block sends app1.example.com to the first application:

Rank #2
Windex Gaming Cleaning Wipes, Pre-Moistened Wipes to Instantly Clean all Gaming Gear and Electronics, Resealable Packaging for a Freshness Lock, 25 count (Pack of 1)
  • 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
server {
    listen 80;
    server_name app1.example.com;

    location / {
        proxy_pass http://127.0.0.1:3001;
        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;
    }
}

Copy the block for each additional application, changing both server_name and the local port. The forwarded headers preserve the original host, client address, proxy chain, and request scheme so the application can generate correct URLs and log useful client information. The NGINX guide shows the same proxy-header pattern.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check and reload safely

  1. Save the file in the Nginx configuration location used by your distribution and enable it according to that distribution’s convention.
  2. Run nginx -t. Do not reload if the test reports a syntax or certificate error.
  3. After a successful test, reload Nginx so existing connections can continue while the new configuration is adopted: sudo systemctl reload nginx.
  4. Resolve each hostname and request it over HTTP. Confirm that each response comes from the intended application rather than another server block.

A typo in server_name, a duplicate default server, or a wrong proxy_pass port can make a valid application appear to be broken. Check the active configuration and Nginx error log when the hostname reaches the wrong app.

Choose subdomain or path routing

Routing style Example Advantages Costs and caveats
Subdomain app1.example.com One clear server block and one independent origin per app; applications usually need no URL-prefix changes. Requires DNS records and certificates covering every hostname.
Path example.com/app1 Fewer hostnames and a shared top-level domain. Each application must tolerate a URL prefix; static assets, redirects, cookies, and generated links may need prefix-aware configuration. Nginx locations become more complex.

Use subdomains unless the applications are designed to run below a common path. Path routing is not just a different Nginx line: the application must know that its public base URL is, for example, /app1, and it must generate asset and redirect URLs accordingly.

Run applications under a process supervisor

PM2 for a straightforward multi-app setup

PM2 can keep separate applications online and restart them after a crash. Its production pattern places Nginx in front of a Node.js process listening on an internal port: PM2 Nginx production setup. Give every process a distinct name and port:

pm2 start app.js --name app1
pm2 start server.js --name app2
pm2 save

Use the actual entry file and environment configuration for each project. Configure PM2’s startup integration for the operating system so the saved process list is restored after a reboot, then perform a reboot test rather than assuming it worked.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
LISEN Cell Phone Stand Phone Holder for Desk, Office Decor Gadgets for Men
  • 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)

systemd when you want native service units

systemd is the operating system’s service manager on many Linux distributions. A unit per application provides explicit user, working-directory, environment, restart, and dependency settings. It is a good fit when your team already manages services through unit files and journal logs. PM2 is often quicker for JavaScript-focused teams, while systemd reduces the number of runtime layers.

Concern PM2 systemd
Application management JavaScript-oriented CLI and process list. Native service units and operating-system tooling.
Restart and reboot recovery Configured through PM2 startup and saved processes. Configured with unit restart policies and enablement.
Logs PM2 log commands and files. System journal and standard service logging.
Operational complexity Fast to add several Node processes; another daemon to maintain. More explicit configuration; consistent with other Linux services.

Do not use both supervisors for the same process. Two managers trying to start one app can create duplicate listeners and confusing restart loops.

Use PM2 cluster mode only for a single app’s CPU scaling

Port separation and clustering solve different problems. To run one application across available CPUs, PM2 documents:

pm2 start app.js -i max

PM2 defines max as automatically detecting the available CPUs and starting as many processes as possible; see the PM2 load-balancing guide. Cluster workers share the application entry point and are not a replacement for assigning different applications their own ports.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Clustered applications must be stateless. PM2 specifically requires shared state such as sessions, caches, and other process data to be externalized before clustering. If a user’s session exists only in one worker’s memory, the next request may reach another worker and appear logged out or lose state. Make state external before enabling -i max, and verify that the application’s libraries support the chosen cluster behavior.

Rank #4
Ledagic IC+RGBW USB Powered Led Light Bar with App & Remote Control, 2 Pack
  • 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

Add HTTPS and redirect HTTP

Terminate TLS at Nginx

Nginx can accept encrypted connections and forward plain HTTP over the loopback interface. Its SSL module provides HTTPS support and depends on OpenSSL: Nginx HTTP SSL module documentation. Configure a certificate and private key in the HTTPS server block:

server {
    listen 443 ssl;
    server_name app1.example.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/private-key.pem;

    location / {
        proxy_pass http://127.0.0.1:3001;
        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;
    }
}

Use the certificate and key paths issued for the hostname, protect the private key from unprivileged users, and follow Nginx’s current HTTPS configuration guidance at Configuring HTTPS servers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Redirect port 80

server {
    listen 80;
    server_name app1.example.com;
    return 301 https://$host$request_uri;
}

Repeat the HTTPS and redirect blocks for every hostname or use a certificate that legitimately covers the names you operate. Validate with nginx -t after adding certificates and reload only after the test succeeds.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Proxy WebSockets explicitly

Normal HTTP proxying does not automatically perform the WebSocket upgrade. In the location used by a WebSocket endpoint, include HTTP/1.1 and the upgrade headers documented by NGINX:

location /socket/ {
    proxy_pass http://127.0.0.1:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    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;
}

Define the connection variable in the Nginx http context, outside a server block:

Best Value
Sale
HUANUO FlowLift™ Dual Monitor Stand, Fully Adjustable Gaming Monitor Desk Mount for 13–32″ Computer Screens, Full Motion VESA 75x75/100x100 with C-Clamp & Grommet Base, Each Arm Holds 4.4 to 19.8 lbs
  • 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.
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Use the actual WebSocket path exposed by the application. If ordinary pages work but a socket repeatedly disconnects, inspect these headers, the endpoint path, and the application’s origin or authentication checks.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Secure the boundary and the applications

  • Expose only ports 80 and 443 publicly. Keep Node.js listeners on 127.0.0.1 or behind a private firewall rule.
  • Run applications as non-root users where practical and keep each project’s writable directories narrow.
  • Store environment files and private keys outside public static directories, with permissions that exclude unrelated service accounts.
  • Use the forwarded scheme and host headers deliberately. If an application trusts proxy headers, configure its trusted-proxy policy rather than accepting arbitrary client-supplied values.
  • Keep Nginx, Node.js, and application dependencies maintained according to the operating system and project release policies.

Verify deployment before adding more workloads

  1. Resolve every DNS name to the VPS and confirm the intended hostname appears in the request.
  2. Request each application over HTTPS and verify that the certificate matches that hostname.
  3. Check normal pages, API routes, redirects, uploads, and static assets.
  4. If the app uses WebSockets, test a real connection through the public hostname.
  5. Stop one application and confirm its supervisor restarts it without affecting the other apps.
  6. Reboot the VPS and verify that Nginx, every supervisor, and every application return automatically.
  7. Review Nginx access and error logs together with application logs.
  8. Watch memory, CPU, disk space, and application errors before deploying another workload.
  9. Confirm that direct requests to ports such as 3001 and 3002 are blocked from the Internet.

Troubleshoot by symptom

Symptom Likely cause Checks and fix
Nginx reports a configuration error Syntax mistake, duplicate directive, or invalid certificate path. Run nginx -t, correct the reported file and line, then test again before reloading.
502 Bad Gateway The app is stopped, listening on another port, or bound to an inaccessible address. Check the supervisor status and test the exact 127.0.0.1:port target locally; align proxy_pass with the app’s environment.
Wrong app answers for a domain DNS points elsewhere, server_name is wrong, or another default server catches the request. Verify DNS, the Host header, and the enabled server blocks.
HTTP works but HTTPS fails Certificate/key mismatch, missing 443 block, or TLS configuration error. Check certificate paths and names, run nginx -t, and inspect the Nginx error log.
WebSocket disconnects Missing upgrade headers, wrong location path, or an application-level origin/authentication failure. Use the WebSocket location template, confirm the map is in the http context, and test the endpoint through the public hostname.
App disappears after reboot Supervisor startup integration was never enabled or the saved process/unit configuration is incomplete. Enable the PM2 startup integration or systemd unit, reboot deliberately, and inspect service logs.
Users lose sessions after clustering State is stored in one worker’s memory. Externalize sessions, caches, and other shared state before using PM2 cluster mode.

How many apps can one VPS run?

There is no universal application count or VPS size in the cited documentation. Capacity depends on each workload’s memory footprint, CPU demand, traffic, background jobs, database use, and logging volume. Begin with one app, measure memory and CPU under representative traffic, and add workloads only while there is safe headroom. A process that is idle most of the time may consume little CPU but still reserve substantial memory; a build worker or real-time service can be CPU-intensive even with few HTTP requests.

When one server approaches its limits, reduce unnecessary workers, move stateful services to appropriate shared infrastructure, or split applications across servers. PM2 clustering can use additional CPUs for a stateless application, but it does not create more memory and does not remove the need to size the VPS for the combined workload.

Operational checklist

  • DNS records point every hostname to the VPS.
  • Each app has its own directory, service identity, environment, and localhost port.
  • Nginx has one tested server block per hostname.
  • Ports 80 and 443 are the only public listeners.
  • HTTPS certificates, keys, and HTTP redirects are configured.
  • WebSocket upgrade headers are present where required.
  • PM2 or systemd restarts processes and survives reboot.
  • Logs, resource usage, and firewall behavior are checked after deployment.

With this arrangement, adding an application is a repeatable operation: deploy it on a new private port, create its hostname’s server block, validate and reload Nginx, issue its certificate, and test recovery. The public interface remains stable while the individual Node.js processes stay isolated behind the proxy.

Frequently Asked Questions

Can multiple Node.js apps share port 80 directly?

No. A single process normally owns a listening address and port. Keep Nginx on the public port and assign each Node.js app a different localhost port behind it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should every app use PM2 cluster mode?

No. Cluster mode is for scaling one stateless application across CPUs. Separate applications still need independent process names, configuration, and port assignments.

Do I need a separate VPS for every domain?

No. One VPS can serve many hostnames when Nginx has a matching server block for each and the server has enough CPU, memory, disk, and network capacity for the combined workloads.

Why keep Node.js ports private if Nginx already proxies them?

Private listeners prevent clients from bypassing hostname routing, TLS, access controls, and logging at Nginx. Expose only the proxy’s public ports.

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.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.