Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober 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 PC×
Skip to content
VGSources
Blog

How to Install Express and Set Up Socket.IO on a VPS

Deploy Express and Socket.IO reliably on a VPS by sharing one Node HTTP server, supervising it with PM2 or systemd, and configuring Nginx for WebSocket upgrades and heartbeat timeouts.
Length11 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • 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
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.
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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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

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 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
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.

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

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.

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)

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.

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

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
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

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.

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

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
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.

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.

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

Verify the public deployment in a controlled order

  1. Check Node directly: run curl -s http://127.0.0.1:3000/health on the VPS and confirm the JSON response.
  2. Check the supervisor: inspect pm2 status and pm2 logs, or systemctl status realtime-app.service and journalctl -u realtime-app.service, for startup errors.
  3. Check Nginx externally: request https://example.com/health from a client outside the VPS and confirm that Nginx reaches the application.
  4. Check Socket.IO: connect with your client using the public HTTPS origin and verify that the client’s connect event fires. The server should log the socket ID.
  5. 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.
  6. 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_pass points 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, and Connection "upgrade" are present in the active location block.
  • Set proxy_read_timeout above pingInterval + 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.

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

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.

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.1 and expose only the intended web ports through Nginx and the VPS firewall.
  • Use HTTPS for the public client origin and set CLIENT_ORIGIN narrowly.
  • 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.

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

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.

Leave a Reply

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

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.

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
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.