October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk11 min

How to Run Multiple Node.js Apps on One Domain with Nginx

A practical NGINX reverse-proxy guide for hosting multiple Node.js apps behind one domain, including path and subdomain routing, proxy_pass slash behavior, TLS, PM2 clustering, WebSockets and failure diagnosis.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run each Node.js app on its own private localhost port, then let NGINX listen on ports 80 and 443 and reverse-proxy each request to the correct port. Use URL prefixes such as example.com/app1/ and example.com/app2/ when one hostname should contain several applications, or use separate subdomains with separate server_name blocks when each app should behave as if it owns the root path.

This arrangement gives you one public entry point, centralized TLS termination, independent Node processes, and a clear place to handle headers, WebSockets, redirects, logging and load balancing.

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.

How the architecture works

Only NGINX needs to be reachable from the internet. Each Node.js service listens on a different loopback port, for example:

Component Public address Private listener
NGINX http://example.com and https://example.com Ports 80 and 443
First Node app https://example.com/app1/ 127.0.0.1:3001
Second Node app https://example.com/app2/ 127.0.0.1:3002

A browser connects to NGINX. NGINX chooses a location by hostname and path, opens a connection to the matching local port, and returns the Node app’s response. The browser never needs to know the private ports.

#1 Best Overall
Sale
TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones | IPX5 Waterproof,2 Mics for AI Calls,Immersive Premium Sound Bass Headset with Charging Case,32 EQ via App Black
  • [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
  • [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
  • [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
  • [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
  • [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.

Keep Node listeners on 127.0.0.1 unless another machine intentionally needs direct access. Binding to all interfaces can expose an app outside NGINX, bypassing TLS, access controls and request logging.

Choose URL paths or subdomains

Both designs use the same reverse-proxy principle, but they impose different requirements on your applications and DNS.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Decision factor Path prefixes Subdomains
Example example.com/app1/ app1.example.com
NGINX structure Several location blocks in one server One server block per hostname
Application base path App must generate links, redirects and assets below its prefix App can normally assume it runs at /
DNS One hostname record Each hostname needs a DNS record, or a suitable wildcard record
TLS One certificate can cover the main hostname Certificate must cover every subdomain, commonly with multiple names or a wildcard
Cookies Path-specific cookies can isolate apps, but defaults need checking Host-only cookies naturally separate applications
URL clarity Compact URLs under one site Clear service boundaries and simpler app assumptions
Local development Requires testing the prefix exactly Often maps cleanly to separate local hostnames or ports

Choose paths when the applications are sections of one site and shared navigation or a single origin matters. Choose subdomains when the services are independent, already expect to own /, or require separate cookie and security boundaries.

Prepare every Node.js application

Give each process a distinct port

Set an explicit port in each app’s environment or startup command. A minimal Express-style listener is:

const port = process.env.PORT || 3001;
app.listen(port, '127.0.0.1', () => {
  console.log(`Listening on ${port}`);
});

Start the second service with a different value, such as PORT=3002. Do not make two processes compete for the same port; the second process will fail to bind and NGINX will have no healthy backend for that route.

Make the app aware of a path prefix

With a path-based design, the browser requests /app1/, but your application may be written as though it lives at /. Decide whether NGINX will remove the prefix before forwarding or preserve it, then configure the router and generated URLs consistently.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
Smart Watch for Men Women Compatible with iPhone Samsung Android Phone 1.69 inch Full Touch Screen IP68 Waterproof Bluetooh Fitness Tracker Heart Rate/Sleep Monitor (Black)
  • 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
  • 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
  • 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
  • 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
  • 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.

In the common configuration below, proxy_pass http://app1_backend/; includes a trailing slash. NGINX replaces the portion matching /app1/ with /, so a browser request for /app1/css/site.css reaches the backend as /css/site.css. The app can therefore continue to serve root-relative routes internally, while its public links must still include /app1/.

Frameworks differ in how they set a public base URL. Configure that setting, mount the router under the prefix, or generate absolute URLs from a trusted public-origin setting. Test HTML, JavaScript bundles, CSS, images, redirects and form actions; a page that loads at /app1/ but requests assets from / will appear broken even though proxying is working.

Trust the proxy only as appropriate

Applications often need to know that the original request was HTTPS so they can create secure redirects and cookies. Configure the framework’s proxy-trust option deliberately rather than accepting arbitrary forwarded headers from direct internet traffic. NGINX should be the only public listener, and the app should use the forwarded protocol and host supplied by that trusted proxy.

Configure path-based routing

Place the upstream definitions in the http context and route each prefix in the public server block:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
http {
    upstream app1_backend {
        server 127.0.0.1:3001;
    }

    upstream app2_backend {
        server 127.0.0.1:3002;
    }

    server {
        listen 80;
        server_name example.com;

        location /app1/ {
            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_pass http://app1_backend/;
        }

        location /app2/ {
            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_pass http://app2_backend/;
        }
    }
}

Understand the trailing slash in proxy_pass

The URI part of proxy_pass changes what the backend receives:

Location Directive Request sent upstream
location /app1/ proxy_pass http://app1_backend/; /app1/orders becomes /orders
location /app1/ proxy_pass http://app1_backend; /app1/orders remains /app1/orders

Use the first form when the app is designed to receive root-relative paths. Use the second only when the application itself expects the prefix. Mixing the two assumptions causes 404 responses, duplicated prefixes such as /app1/app1/, or redirects to the wrong URL.

Rank #3
New Bee Guitar Cable 10ft Electric Instrument Bass AMP Cord
  • [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
  • [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
  • [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
  • [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
  • [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by

Handle the prefix without an accidental fall-through

A request for /app1 does not include the trailing slash in /app1/. Redirect it explicitly so relative links resolve predictably:

location = /app1 {
    return 301 /app1/;
}

Repeat the exact-match redirect for each application. Keep the more specific locations before generic locations in your own configuration for readability. NGINX selects the longest matching prefix when several prefix locations could match, so a dedicated /app1/ block takes precedence over a broad / block.

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

Preserve the original request information

The header directives in the example let the app see the public host and the originating client address. They are important for absolute URL generation, audit logs, rate limits and security decisions. If another proxy or load balancer sits in front of NGINX, define a trusted chain instead of blindly treating every incoming X-Forwarded-For value as genuine.

Configure subdomain routing

Subdomains avoid most base-path work. Give each hostname its own server block and route the root path to a different upstream:

http {
    upstream app1_backend {
        server 127.0.0.1:3001;
    }

    upstream app2_backend {
        server 127.0.0.1:3002;
    }

    server {
        listen 80;
        server_name app1.example.com;

        location / {
            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_pass http://app1_backend;
        }
    }

    server {
        listen 80;
        server_name app2.example.com;

        location / {
            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_pass http://app2_backend;
        }
    }
}

Here the URI is omitted from proxy_pass, so NGINX forwards the complete request URI. A request for /orders/42 reaches the selected app as /orders/42. Each hostname must resolve to the NGINX machine before testing can succeed.

Put TLS and redirects at NGINX

Terminate HTTPS at NGINX rather than managing public certificates independently in every Node process. Configure certificates for the hostnames you actually serve, then redirect clear-text requests to HTTPS:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
BSIMB 15.6" Digital Family Calendar & Chore Chart, No Subscription Fees
  • Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
  • Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
  • All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
  • Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
  • Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.
server {
    listen 80;
    server_name example.com;
    return 301 https://example.com$request_uri;
}

The HTTPS server retains the same location and proxy rules while listening on 443 and loading the certificate and private key issued for the hostname. For subdomains, include every served name in the certificate strategy and redirect each HTTP hostname to its corresponding HTTPS URL.

After changing certificates or TLS settings, validate the NGINX configuration before reloading it. Keep private keys readable only by the account and services that need them, and renew certificates before expiration. Node applications can then remain plain HTTP on loopback, with encryption handled at the edge.

Forward WebSocket connections correctly

普通 HTTP proxying does not automatically complete a WebSocket upgrade. For an app that uses WebSockets, add HTTP/1.1 and forward the upgrade headers in its location:

location /app1/ {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header 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_pass http://app1_backend/;
}

Use the same settings in a subdomain’s root location when that service owns the WebSocket endpoint. Test the upgrade separately from ordinary page loads. Increase the proxy read timeout only when the application’s long-lived connection pattern requires it; an unnecessarily large timeout can keep dead connections around and consume resources.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Run and supervise the Node processes

NGINX does not start, restart or monitor your Node applications. Run each service under a supervisor such as PM2 so crashes are restarted and deployments have a repeatable process.

One managed process per app

Keep separate process names, environment variables and logs for each application. A supervisor configuration should make the port, working directory, production mode and log destinations explicit. Start the apps only after their dependencies, migrations and required secrets are available.

Cluster an app when it is stateless

PM2 can start a Node application in cluster mode with:

pm2 start app.js -i max

The -i max option creates workers across the available CPUs. NGINX can also load-balance several independently started instances through one named upstream:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
upstream app1_backend {
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

PM2’s built-in load balancer is intended for networked Node applications that can be scaled across CPUs without code changes, but clustering is safe only when the app is suitable for stateless operation. In-memory sessions, upload state, WebSocket presence and local caches are not shared automatically between workers. Store sessions and other shared state in an external, shared system, or use a persistence strategy that remains correct when a later request reaches another worker.

Do not run two unrelated applications on the same port merely to use a cluster. Each app needs its own process definition and upstream; scaling an app means adding instances of that app, not mixing services.

Deploy changes without taking down every app

  1. Build or deploy one Node application in its own directory and update only its environment and process definition.
  2. Restart or reload that application’s supervisor process. Confirm that its local port accepts requests before changing NGINX.
  3. Edit the relevant NGINX upstream or location. Keep unrelated applications’ blocks unchanged.
  4. Run an NGINX configuration test. A syntax error must be fixed before any reload.
  5. Reload NGINX so existing connections can finish while new requests use the validated configuration.
  6. Test every public path or hostname, including redirects, static assets, authenticated pages and WebSocket upgrades.

Use distinct application and NGINX logs. A successful NGINX reload proves only that the configuration parsed; it does not prove that a Node process is healthy or that its router understands the chosen prefix.

Diagnose common failures

Symptom Likely cause What to check
502 Bad Gateway Node is stopped, listening on another port, or bound to an unreachable address Check the supervisor status, confirm the local listener and compare it with the upstream port; read the NGINX error log and the app log.
Every app shows the same content Requests are landing in the default server or a broad location Verify the request’s hostname, DNS record and exact server_name; inspect which server block is selected.
Routes work but CSS or JavaScript returns 404 The app emits root-relative asset URLs while it is published under a prefix Set the app’s public base path or adjust asset generation; verify whether proxy_pass strips the prefix.
Redirects point to localhost or HTTP The app does not trust or receive the original host and protocol Forward Host, client-address and protocol headers, then configure the framework’s trusted-proxy behavior.
/app1 fails but /app1/ works No exact-match redirect exists Add location = /app1 { return 301 /app1/; }.
Backend receives an unexpected prefix The URI part of proxy_pass is present or absent contrary to the app’s routing model Compare the two slash forms and test the actual upstream request path.
WebSocket handshake fails or drops quickly Upgrade headers or HTTP/1.1 are missing, or the timeout is too short Add the upgrade directives, test the endpoint directly and inspect both logs.
Users see another user’s session Cluster workers share no in-memory session state Move sessions to shared storage or use a persistence design that works across workers.
Configuration reload is refused Syntax error, missing certificate file or invalid directive context Run the configuration test, correct the reported file and line, then reload again.

Cookies, security and observability

Scope cookies deliberately

Path-based apps share an origin, so review cookie names, Path, Domain, Secure and SameSite attributes. Give unrelated apps distinct cookie names and narrow path scope where possible. Subdomains provide stronger default separation for host-only cookies, but a deliberately broad parent-domain cookie can still be sent to every subdomain.

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

Keep the proxy boundary explicit

  • Expose only ports 80 and 443 publicly unless another port is required for administration.
  • Bind Node services to loopback and restrict direct access with the host firewall.
  • Use HTTPS for all public routes and set secure cookie behavior in production.
  • Do not trust arbitrary client-supplied forwarding headers when NGINX is not the only proxy.
  • Give each service separate secrets, environment files and log files.
  • Limit request body sizes and timeouts according to the application rather than applying one unsafe global value.

Make failures diagnosable

Record the hostname, public path, request identifier, status and upstream timing where practical. When a request fails, correlate the NGINX access and error logs with the matching Node log entry. This distinguishes DNS or TLS problems from route selection, proxy connectivity and application exceptions.

Use named upstreams for growth

A named upstream is useful even with one backend because it separates routing policy from a raw address. When an app gains another instance, add a server line to that upstream instead of rewriting every location. NGINX’s default upstream algorithm is round robin, distributing requests across the listed servers.

Scaling changes the operational requirements: health, shared sessions, background jobs, file uploads and WebSocket affinity all need an explicit design. A second instance improves CPU utilization and restart flexibility only if the application remains correct when successive requests reach different workers.

Choose an implementation with this checklist

  • Use path prefixes if one hostname and a unified navigation model are more important than zero app changes.
  • Use subdomains if each service should own /, needs independent cookies, or is maintained by a separate team.
  • Choose a trailing-slash proxy_pass when NGINX should remove the public prefix; omit the URI only when the backend must receive the complete path.
  • Use a named upstream when you expect more than one instance or want a clean separation between route and backend address.
  • Add WebSocket upgrade directives only to locations that need them, and test long-lived connections explicitly.
  • Keep TLS, redirects and public security policy at NGINX while Node handles application behavior on private ports.

Final verification checklist

  1. Resolve every hostname to the NGINX host and confirm the intended certificate name.
  2. Confirm each Node process is supervised, healthy and listening on its assigned loopback port.
  3. Validate the NGINX configuration before reloading.
  4. Request the bare prefix and trailing-slash form, checking that redirects are intentional.
  5. Open pages through each public URL and inspect asset, API and redirect requests in the browser.
  6. Verify forwarded host, protocol and client-address values in application logs.
  7. Exercise authentication, cookies, uploads and WebSockets where those features exist.
  8. Review NGINX error logs and application logs after deployment, not only the browser response.

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 from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

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.