Run Express and Socket.IO from the same Node.js HTTP server, keep that server bound to 127.0.0.1, place Nginx in front of it, and use one process supervisor to survive crashes and reboots. The deployment below covers installation, WebSocket proxying, proxy-aware Express settings, TLS, verification, and the extra requirements for scaling beyond one process.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
What the finished deployment looks like
A browser or game client connects to your public HTTPS hostname. Nginx accepts the HTTP request and Socket.IO upgrade, then forwards both ordinary HTTP and WebSocket traffic to a private Node.js listener on the VPS. Express handles routes such as /health; Socket.IO uses the same underlying HTTP server for its polling and WebSocket transports.
As an Amazon Associate I earn from qualifying purchases.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated 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 match- Public edge: Nginx listens on ports 80 and 443, redirects HTTP to HTTPS, and forwards traffic.
- Application: Express and Socket.IO share one server created with Node’s
http.createServer(). - Private listener: Node listens on
127.0.0.1, so the application port is not directly exposed to the internet. - Supervisor: PM2 or systemd restarts the process after a crash and starts it after a reboot.
- Scaling boundary: one process needs no Socket.IO adapter; multiple workers or hosts need sticky sessions and a cross-worker adapter.
This arrangement suits a real-time game lobby, chat service, matchmaking status page, or any other browser client that needs a persistent connection without exposing Node’s port directly.
Prerequisites on the VPS
You need a VPS account with administrative access, a DNS name pointed at the server, and a supported Node.js installation method for the VPS distribution. Install Node using the provider’s documented package repository, image, or version manager rather than copying binaries from an unrelated system. Confirm both executables before creating 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.
node --version
npm --version
You also need Nginx installed and a firewall policy that allows the public web ports required by your distribution. Keep the Node application port private; only Nginx should need to reach it locally.
Create the Express and Socket.IO application
Initialize a project and install dependencies
Choose an application directory, initialize a package manifest, and install the two runtime dependencies:
mkdir my-realtime-app && cd my-realtime-app
npm init -y
npm install express socket.io
The commands create a CommonJS project by default. The following server uses the same module style, so it can be started without changing package.json to enable ES modules.
Attach Socket.IO to the Express HTTP server
Create server.js with this minimal, production-friendly wiring:
const express = require('express');
const { createServer } = require('node:http');
const { Server } = require('socket.io');
const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
cors: { origin: process.env.CLIENT_ORIGIN || false }
});
app.get('/health', (_req, res) => res.json({ ok: true }));
io.on('connection', (socket) => {
console.log('connected', socket.id);
socket.on('disconnect', (reason) => console.log('disconnected', reason));
});
const port = process.env.PORT || 3000;
httpServer.listen(port, '127.0.0.1', () => {
console.log(`listening on ${port}`);
});
The important detail is that new Server(httpServer) receives the HTTP server created from the Express app. Do not call app.listen() for Express and then create an unrelated listener for Socket.IO; that would leave Socket.IO detached from the public server.
CLIENT_ORIGIN should be the exact browser origin when your client is hosted elsewhere, including its scheme and port where applicable. Leaving the value unset makes the example restrictive rather than opening cross-origin access broadly. Add authentication and authorization in your connection and event handlers before accepting game actions or private messages.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Run the application locally on the VPS
Start it directly once to catch syntax and dependency errors before adding a supervisor:
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
node server.js
In a second shell on the VPS, request the private health endpoint:
curl -s http://127.0.0.1:3000/health
A healthy process returns JSON containing "ok":true. Stop the foreground process with Ctrl+C after this check. Production should not depend on a shell session remaining open.
Keep Node running after crashes and reboots
Express’s production guidance distinguishes a development command such as node server.js from a production process manager or operating-system init system. Choose one supervisor for a simple deployment. Running PM2 and systemd against the same process can create competing restart policies and confusing logs.
Free tools Windows power users keep installed
One-click scans. No signup required.
Option A: PM2
Install PM2 globally, start the application with a descriptive name, save the process list, and generate its boot integration:
sudo npm install -g pm2
pm2 start server.js --name realtime-app
pm2 save
pm2 startup
pm2 startup prints a command that must be run with the required privileges. Execute that printed command, then run pm2 save again if PM2 asks you to persist the list. The saved list is what PM2 restores after a reboot.
Use these commands during deployment and diagnosis:
pm2 status
pm2 logs realtime-app
PM2 is convenient when you want application-oriented commands, a compact log view, or a later move to cluster mode. Cluster mode is not required for one process and should not be enabled casually: it changes the Socket.IO requirements described in the scaling section.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
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)
Option B: systemd
systemd is the operating system’s init and service manager. Express documents a unit-file pattern with an explicit executable, working directory, production environment, and automatic restart. Create a unit such as /etc/systemd/system/realtime-app.service:
[Unit]
Description=Express and Socket.IO application
After=network.target
[Service]
Type=simple
WorkingDirectory=/var/www/my-realtime-app
ExecStart=/usr/bin/node /var/www/my-realtime-app/server.js
Environment=NODE_ENV=production
Environment=PORT=3000
Restart=always
RestartSec=5
User=nodeapp
[Install]
WantedBy=multi-user.target
Use the actual Node path from command -v node, an account that owns or can read the application directory, and the real project path. Then load, enable, and start the unit:
sudo systemctl daemon-reload
sudo systemctl enable --now realtime-app.service
sudo systemctl status realtime-app.service
sudo journalctl -u realtime-app.service
Restart=always asks systemd to bring the process back after an exit. The enabled unit starts during the normal boot target. journalctl provides the service’s stdout and stderr, while systemctl status shows whether the latest start succeeded.
Which supervisor should you choose?
| Decision area | PM2 | systemd |
|---|---|---|
| Crash recovery | Restarts the named Node process and exposes PM2 status. | Uses the unit’s restart policy, such as Restart=always. |
| Boot persistence | Requires pm2 startup and a saved process list. |
Requires enabling the service with systemctl enable. |
| Logs | pm2 logs shows application output. |
journalctl -u reads the system journal. |
| Deployment ergonomics | Application-focused start, status, and log commands. | Native operating-system service configuration. |
| Privilege boundary | Runs under the account that starts PM2 unless configured otherwise. | The unit can specify a dedicated User and fixed paths. |
| Cluster use | Cluster mode is available but introduces Socket.IO affinity and adapter requirements. | Additional workers require separate service or process design and the same Socket.IO scaling considerations. |
For a single VPS and one Node process, either choice is sufficient. Pick the tool your team already monitors and document its exact start, stop, log, and rollback commands.
Configure Nginx for HTTP and WebSocket traffic
Use a reverse-proxy server block
Point a DNS record such as example.com at the VPS, then configure an Nginx server block. This representative configuration forwards normal HTTP requests and the WebSocket upgrade:
server {
listen 80;
server_name 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";
proxy_read_timeout 75s;
}
}
The HTTP/1.1 setting and the Upgrade and Connection headers are essential for a WebSocket handshake. Without them, a client may remain on polling or fail when it attempts to upgrade.
The timeout must exceed Socket.IO’s heartbeat window. Socket.IO documents a default pingInterval + pingTimeout total of 45 seconds and notes that Nginx’s documented default proxy_read_timeout is 60 seconds. The example uses 75 seconds to leave headroom. If you customize Socket.IO’s heartbeat values, raise Nginx’s timeout above the new sum as well.
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
Validate the configuration with your distribution’s Nginx test command before reloading it. Once the test passes, reload Nginx rather than stopping it, so existing connections have the least disruption.
Add HTTPS before exposing the service
Use the certificate tooling supported by your VPS distribution to obtain a certificate for the hostname, configure Nginx to listen on 443, and redirect port 80 to HTTPS. Then set the client origin to the public https:// URL. A browser page loaded over HTTPS should not be asked to open an insecure Socket.IO endpoint; mixed-content protection will block it.
Keep the internal proxy target as http://127.0.0.1:3000 unless you have a specific reason to encrypt loopback traffic. TLS terminates at Nginx in this layout, while the private hop never leaves the VPS.
Tell Express which proxy headers to trust
Nginx supplies forwarding headers so Express can determine the original client address, protocol, and host. Express’s trust proxy setting must match the real topology, not simply be enabled for every address.
When Nginx is local
If Nginx is the only proxy and runs on the same VPS, a narrow setting is:
app.set('trust proxy', 'loopback');
Place it after creating app and before handling requests. This allows Express to use headers received from the loopback proxy.
When another proxy is in front
If traffic passes through a load balancer or another known hop, trust the actual proxy address or subnet instead of blindly trusting all forwarded values. The correct value depends on your network topology. Express warns that an overly broad trust rule can let a client influence the apparent IP address and protocol by supplying forged forwarding headers.
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.
Configure the edge proxy to overwrite X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto, rather than append unverified client values as if they were authoritative. Correct proxy trust matters when your application uses secure cookies, req.ip, req.protocol, or req.hostname.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsVerify the public deployment in a controlled order
- Check Node directly: run
curl -s http://127.0.0.1:3000/healthon the VPS and confirm the JSON response. - Check the supervisor: inspect
pm2 statusandpm2 logs, orsystemctl status realtime-app.serviceandjournalctl -u realtime-app.service, for startup errors. - Check Nginx externally: request
https://example.com/healthfrom a client outside the VPS and confirm that Nginx reaches the application. - Check Socket.IO: connect with your client using the public HTTPS origin and verify that the client’s
connectevent fires. The server should log the socket ID. - Check idle connections: leave a client idle beyond the normal heartbeat interval. Nginx should keep the connection alive; if it closes, inspect browser, Nginx, and Node logs and compare the timeout with the heartbeat sum.
- Check reboot recovery: during planned maintenance, reboot the VPS and verify that the selected supervisor restores the application without a manual shell command.
Perform the checks in this order so a failure identifies a layer: application, supervisor, proxy, public TLS path, or long-lived connection handling.
Common failure modes and targeted fixes
The health route works locally but not through Nginx
- Confirm Nginx’s
proxy_passpoints to the same address and port used by Node. - Check the server name and DNS record, then inspect Nginx’s error log for connection-refused or name-mismatch errors.
- Verify the Node process is still running under PM2 or systemd rather than only in a closed terminal.
Socket.IO never upgrades or disconnects during idle time
- Ensure
proxy_http_version 1.1,Upgrade, andConnection "upgrade"are present in the active location block. - Set
proxy_read_timeoutabovepingInterval + pingTimeout; the documented defaults total 45 seconds, while 75 seconds is a practical margin. - Reload Nginx after editing and test the configuration before the reload.
Secure cookies or client IPs are wrong
Review app.set('trust proxy', ...) against the actual proxy addresses. Do not use an unrestricted trust rule merely to make req.protocol report HTTPS. Also verify that the proxy overwrites, rather than blindly accepts, the forwarded headers.
The process disappears after logout or reboot
A foreground node server.js process is tied to the shell. Start it under PM2 and save the process list, or install and enable the systemd unit. Check the supervisor’s logs for an invalid Node path, wrong working directory, missing environment variable, or permission error.
The client connects but broadcasts miss some users
This is expected when you split Socket.IO across workers or hosts without a cross-worker adapter. A single process does not need an adapter. Multiple processes require both connection affinity and an adapter that distributes events between workers.
Recommended Free Tools
Know when one process is no longer enough
One VPS, one process
The configuration in this guide is the simplest operating model: one Node process owns all Socket.IO connections, and Nginx forwards to it. No Socket.IO adapter is required. A supervisor still remains necessary for crash and reboot recovery.
Quick Recap
PM2 cluster mode or several Node workers
When polling is enabled, a client can make related requests that must reach the same worker. Socket.IO therefore requires sticky sessions so a client’s polling requests maintain connection affinity. You also need a cross-worker adapter so an event emitted by one worker reaches sockets connected to another worker.
Several VPS hosts
Multiple hosts add the same two Socket.IO requirements—sticky sessions and an adapter—plus network, health-check, deployment, and failure-management concerns. A shared adapter such as Redis may be used in a multi-host design, but verify its compatibility and operational requirements for your Socket.IO version and environment before making it the default. Scaling out is an architectural change, not just a higher worker count.
Operational checklist for a game-facing service
- Keep the Node port bound to
127.0.0.1and expose only the intended web ports through Nginx and the VPS firewall. - Use HTTPS for the public client origin and set
CLIENT_ORIGINnarrowly. - Run exactly one supervisor for the application and test its boot recovery.
- Keep a health route that does not depend on a Socket.IO connection, so Nginx and monitoring can test the HTTP path independently.
- Log connect and disconnect reasons while diagnosing, but avoid logging authentication tokens or private game payloads.
- Set proxy trust to the addresses you actually operate and review it whenever the topology changes.
- Before enabling workers, plan sticky sessions and a cross-worker adapter; otherwise keep one process.
- After changing Socket.IO heartbeat settings, recalculate the Nginx read timeout instead of retaining an old value.
Final deployment sequence
Create the project and install Express and Socket.IO, wire both to one Node HTTP server, and prove the private health endpoint works. Put the process under either PM2 or systemd, then configure Nginx with HTTP/1.1 upgrade headers and a read timeout longer than the heartbeat period. Add HTTPS, set Express’s proxy trust to your actual topology, and run the local, public, WebSocket, idle-connection, and reboot checks. Stay with one process until you are ready to provide sticky sessions and a cross-worker adapter for a scaled Socket.IO deployment.
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.




