Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
Install Node.js using the method supported by your VPS provider, create an Express project, and attach Socket.IO to the same Node HTTP server. In production, keep Node bound to localhost, put Nginx in front of it for HTTP and WebSocket proxying, and run the app under one supervisor such as PM2 or systemd so crashes and reboots recover automatically.
The procedure below gives you a working health endpoint, a Socket.IO connection, Nginx upgrade handling, proxy-aware Express settings, and a verification plan for a single-VPS deployment.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →How the production setup fits together
A browser or other Socket.IO client connects to your public HTTPS hostname. Nginx receives the request, serves as the public TLS and HTTP entry point, and forwards traffic to Node on 127.0.0.1:3000. Express handles normal HTTP routes while Socket.IO handles its polling and WebSocket transports on the same underlying HTTP server.
- Client: uses the public HTTPS origin.
- Nginx: forwards HTTP/1.1 requests and WebSocket upgrade headers.
- Node: listens privately on localhost.
- Express: serves routes such as
/health. - Socket.IO: is attached to the Node HTTP server and handles real-time connections.
- Supervisor: restarts the process after a crash and restores it at boot.
Do not start Express with one listener and Socket.IO on an unrelated listener. Create the HTTP server from the Express app, pass that server to new Server(...), and call listen on the resulting HTTP server. This shared listener is what lets ordinary routes and Socket.IO’s handshake and upgrades use the same public hostname and proxy path.
#1 Best Overall
- Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
- With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
- Wide Application:Upgraded attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
- Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
- Warranty & Support: Our Electric air duster comes with 5 years warranty and 24/7 customer service. During this period, if you have any questions,pls kindly feel free to contact us.
Prerequisites on the VPS
- SSH access to a Linux VPS and an account with permission to install software and configure Nginx.
- Node.js installed through the VPS distribution or provider method that it officially supports. Use a currently supported Node.js release for your application; no particular major version is required here.
- A DNS name pointing to the VPS if you will expose the service through a domain.
- Inbound access for the public web ports required by your Nginx configuration. Keep the Node application port private.
- Your frontend’s exact origin, if it is hosted separately from the API and Socket.IO server.
Obtain TLS for the hostname using the certificate tooling appropriate to your VPS distribution. The Nginx example later can then be paired with an HTTP-to-HTTPS redirect and the certificate paths generated by that tooling. Before opening the public URL, confirm that the VPS firewall permits the ports Nginx actually listens on and does not expose port 3000 unnecessarily.
Create the Express and Socket.IO application
1. Initialize the project
After connecting over SSH, create a directory and install the two runtime dependencies:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →mkdir my-realtime-app && cd my-realtime-app
npm init -y
npm install express socket.io
The commands create package.json and install Express and Socket.IO locally in the project. Keep the project directory and its ownership consistent with the account that will run the service. If you deploy as a dedicated account, that account must be able to read the application files and the installed node_modules directory.
2. Use one Node HTTP server
Create server.js with this CommonJS example:
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}`);
});
createServer(app) creates the Node HTTP server that Express uses. Passing it to new Server(httpServer) attaches Socket.IO to that same server. The listener is explicitly bound to 127.0.0.1, so clients cannot bypass Nginx by connecting directly to port 3000. The health route is intentionally small: it gives you a reliable test for process, port, and proxy problems without depending on a database or a logged-in user.
The connection and disconnection handlers are also useful during the first deployment. The socket ID in the log confirms that the Socket.IO handshake reached this process; a successful HTTP health response alone does not prove that upgrade requests are configured correctly.
3. Set the browser origin deliberately
The example reads CLIENT_ORIGIN from the environment. If the browser application has a different origin, set that value to the exact scheme, host, and port it uses, for example https://app.example.com. Leaving it unset produces false, which does not enable cross-origin access. Avoid a permissive origin when your application is intended for one known frontend. If the frontend and server share the same origin, no cross-origin allowance is needed for that browser connection.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Run and test the app before adding Nginx
Start it directly for the first smoke test
node server.js
You should see a message showing that the process is listening on port 3000. From a second SSH session on the VPS, call the private health endpoint:
Rank #2
- Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
- Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
- Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
- Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
- Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth
curl -s http://127.0.0.1:3000/health
The expected response is JSON containing {"ok":true}. Stop the foreground process after this test; production should use a supervisor rather than an interactive shell. If this local request fails, fix the Node installation, dependency installation, working directory, port, or application error before changing Nginx.
Keep Node running after crashes and reboots
Express’s production guidance distinguishes a development command such as node server.js from a production process managed by a process manager or the operating system’s init system. Choose one supervisor for this application. Running PM2 and systemd simultaneously can create competing restart and deployment behavior, making it unclear which process owns the port or which logs reflect the current instance.
Option A: PM2
- Install PM2 globally using the Node installation’s package manager:
sudo npm install -g pm2
- Start the application with a stable name:
pm2 start server.js --name realtime-app
- Save the current process list:
pm2 save
- Generate the boot integration command:
pm2 startup
PM2 prints a command that must be run with the required privileges. Run that printed command, then run pm2 save again if PM2 asks you to. Check operation with:
Outdated 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 matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallpm2 status
pm2 logs realtime-app
PM2 is convenient when you want an application-oriented command-line workflow, named processes, and quick log inspection. Its cluster mode is an additional scaling feature, not a requirement for a one-process VPS. Make sure PM2 is started for the same user who owns the application process; otherwise a saved process list can appear to be missing when you inspect it under a different account.
Option B: systemd
systemd is the operating system’s service manager on many Linux distributions. Create a unit such as /etc/systemd/system/realtime-app.service, adjusting the account and paths to your deployment:
[Unit]
Description=Realtime Node application
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/srv/my-realtime-app
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /srv/my-realtime-app/server.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
The ExecStart path must point to the Node binary installed on your VPS. The WorkingDirectory must contain server.js and the installed dependencies. After saving the unit, load and enable it:
sudo systemctl daemon-reload
sudo systemctl enable --now realtime-app
sudo systemctl status realtime-app
sudo journalctl -u realtime-app -f
Restart=always asks systemd to restart the service when it exits, while enable makes it start during boot. Running the service as a dedicated non-root account limits the process’s filesystem privileges. Environment values such as PORT and CLIENT_ORIGIN can be added to the unit or supplied by the deployment environment; keep credentials out of the source file.
Rank #3
- 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
- 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
- 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
- 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
- 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.
PM2 and systemd compared
| Consideration | PM2 | systemd |
|---|---|---|
| Crash restart | Managed by PM2’s process supervisor. | Managed by the operating system with Restart=always or another chosen policy. |
| Boot persistence | Use pm2 startup and save the process list. |
Use systemctl enable for the unit. |
| Logs | pm2 logs and PM2 status commands. |
journalctl and systemctl status. |
| Deployment ergonomics | Fast, application-focused CLI commands and named processes. | Native service files, privilege boundaries, and distribution-level lifecycle control. |
| Cluster mode | Available, but it introduces Socket.IO affinity and adapter requirements. | One service normally represents one process unless you deliberately design a multi-process arrangement. |
For a single VPS, select the supervisor your team can inspect and update reliably. The important properties are recovery after an unexpected exit, startup at boot, accessible logs, and a clear service account—not running both supervisors.
Configure Nginx as the reverse proxy
Nginx must proxy ordinary HTTP requests and preserve the WebSocket upgrade handshake. Add a server block similar to this one:
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;
}
}
Replace example.com with the hostname that resolves to your VPS. The proxy_http_version 1.1, Upgrade, and Connection directives allow the HTTP connection to switch to WebSocket transport. The forwarded headers preserve the original host, client address, and scheme for the application.
Socket.IO’s documented default pingInterval + pingTimeout totals 45 seconds, while Nginx’s documented proxy_read_timeout default is 60 seconds. The example uses 75 seconds to provide headroom. If you change Socket.IO’s heartbeat settings, keep Nginx’s read timeout greater than their sum; otherwise an idle but healthy connection can be closed by the proxy. This is why a connection can work during an active test yet fail after sitting idle.
After validating the configuration with your distribution’s Nginx test command, reload Nginx without stopping active workers. Once TLS is configured, use HTTPS for the public server and redirect plain HTTP to HTTPS with the certificate tooling appropriate to the VPS distribution. Keep the Node listener on localhost even after TLS is enabled: Nginx, not the application process, remains the public entry point and TLS terminator.
Tell Express which proxy headers it may trust
Express needs proxy trust only when your application relies on values derived from forwarded headers, such as secure-cookie decisions, req.ip, req.protocol, or req.hostname. If Nginx runs on the same VPS, a narrow setting is:
app.set('trust proxy', 'loopback');
Place this after creating app and before routes that read those request properties. If the proxy is on another private address or subnet, configure the actual trusted address or subnet instead of blindly trusting every hop.
Recommended Free Tools
Rank #4
- 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
- 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
- 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
- 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
- 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.
Trust must match the real topology. Express warns that accepting forwarded headers from an untrusted path can let a client influence the apparent address and protocol. Configure Nginx or the upstream proxy to overwrite, rather than append blindly to, X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto. A setting that is safe with local Nginx may be unsafe after moving the proxy to another host, so revisit it whenever the network path changes.
Verify the complete deployment
- On the VPS, run
curl -s http://127.0.0.1:3000/health. Confirm the JSON health response before investigating Nginx. - Check the supervisor: use
pm2 statusandpm2 logs, orsystemctl status realtime-appandjournalctl -u realtime-app. Resolve startup errors before testing externally. - From an external client, request
https://example.com/health. A successful response proves DNS, TLS, Nginx routing, and the private Node listener work together. - Connect with a Socket.IO client using the public HTTPS origin and confirm its
connectevent. Watch both browser developer tools and the server log for the socket ID. - Leave the client idle beyond the normal heartbeat interval. It should remain connected; an unexpected close points first to proxy upgrade settings or a read timeout that is too short.
- During a controlled maintenance window, reboot the VPS. Confirm that your chosen supervisor starts the application and that the health endpoint and Socket.IO connection recover afterward.
Test from both the VPS and an external network. A localhost success isolates the Node process; a public health success adds DNS, firewall, TLS, and Nginx; a successful idle Socket.IO session verifies the upgrade and timeout behavior. Keeping those checks separate makes the first failing layer easier to identify.
Troubleshoot the common failure points
| Symptom | Likely cause | What to check |
|---|---|---|
curl to localhost fails |
Node is not running, the wrong working directory is used, or the process listens on another port. | Inspect supervisor status and logs, verify PORT, and confirm ExecStart or the PM2 script path. |
| Local health works but public health fails | DNS, Nginx syntax, firewall rules, TLS, or the proxy_pass target is incorrect. |
Test Nginx’s configuration, inspect its error log, and request the public URL from outside the VPS. |
| Health works but Socket.IO cannot connect | The WebSocket upgrade is not being forwarded, the client origin is rejected, or the client uses the wrong public scheme. | Check proxy_http_version, both upgrade headers, CLIENT_ORIGIN, and browser network details. |
| Connections drop while idle | proxy_read_timeout is not greater than Socket.IO’s heartbeat interval plus timeout. |
Compare the configured heartbeat values with Nginx’s read timeout and raise the timeout with appropriate headroom. |
req.ip or req.protocol is wrong |
Express does not trust the actual proxy, or it trusts an untrusted path. | Set trust proxy to the real loopback address, proxy address, or subnet, and ensure the proxy overwrites forwarded headers. |
| The app returns after a manual start but disappears after logout or reboot | It is still running in a shell rather than under a supervisor. | Choose PM2 or systemd, enable boot persistence, and verify the service after a controlled reboot. |
When one process is no longer enough
For one VPS running one Node process, Socket.IO does not need an adapter. The in-memory connection and room state belong to that process, and every client reaches the same worker through Nginx.
Adding PM2 cluster mode or placing multiple hosts behind a load balancer changes the requirements:
| Deployment | Connection handling | Broadcasting | Operational cost |
|---|---|---|---|
| One VPS, one process | No cross-worker affinity is needed. | No adapter is required. | Simplest setup and failure model. |
| Multiple workers on one host | Sticky sessions are required when polling requests must return to the same worker. | Use a cross-worker adapter so broadcasts reach clients connected to other workers. | More process management and coordination. |
| Multiple hosts | Load-balancer affinity must keep polling traffic on the appropriate worker. | Use a shared adapter, such as a Redis-based design, after verifying compatibility and operational requirements. | Additional shared infrastructure, monitoring, and failure modes. |
Do not enable cluster mode merely to follow a tutorial. First establish that a single supervised process is healthy. Scale only when you can provide both the required sticky-session behavior and a compatible cross-worker adapter. Without affinity, a client’s polling requests can land on different workers; without a cross-worker adapter, an event emitted by one worker will not reach clients connected to another.
A safe update sequence
- Upload or pull the new application files into the deployment directory.
- Install the declared dependencies with
npm installfrom that directory. - Run the local health check before restarting the service.
- Restart the one supervisor you selected:
pm2 restart realtime-apporsudo systemctl restart realtime-app. - Check supervisor logs for startup errors, then test the public health endpoint and a real Socket.IO connection.
Keep environment values such as PORT and CLIENT_ORIGIN in the supervisor or deployment environment rather than hard-coding secrets in source files. Keep Nginx public and Node private; that separation makes proxy headers, TLS, and process recovery easier to reason about. Repeat the idle-connection and reboot checks after changes to Nginx, heartbeat settings, the supervisor, or the network topology.
Frequently Asked Questions
Can Express and Socket.IO listen on different ports?
They can, but that is not the setup shown here. Create one Node HTTP server from the Express app, attach Socket.IO to it, and call listen on that shared server so Nginx can proxy both HTTP and real-time traffic consistently.
Why does Socket.IO work locally but fail through Nginx?
The usual causes are missing HTTP/1.1 or upgrade headers, a rejected CLIENT_ORIGIN, an incorrect public HTTPS URL, or a proxy read timeout that is too short. Check the Nginx directives, browser network details, and the Socket.IO server log.
Best Value
- 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
- 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
- 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
- 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
- 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.
What timeout should Nginx use for Socket.IO?
Nginx’s read timeout must be greater than Socket.IO’s pingInterval + pingTimeout. The documented defaults total 45 seconds; the example uses 75 seconds instead of relying on the 60-second Nginx default.
Do I need Redis for a single VPS?
No. One VPS with one Node process needs no Socket.IO adapter. A shared adapter becomes relevant when multiple workers or hosts must broadcast to one another, and polling traffic also needs sticky sessions.
Should I use PM2 or systemd?
Either is suitable for a simple deployment. PM2 offers an application-focused CLI and named-process logs; systemd provides native service units, operating-system lifecycle control, and clear privilege boundaries. Select one and do not run both for the same process.
How do I make the app start after a reboot?
With PM2, run pm2 startup, execute the privileged command it prints, and save the process list. With systemd, install a unit with a restart policy and run systemctl enable --now realtime-app.
Free tools Windows power users keep installed
One-click scans. No signup required.
When should I set Express trust proxy?
Set it when the app uses proxy-derived values such as req.ip, req.protocol, req.hostname, or secure-cookie behavior. Trust only the actual Nginx address or subnet, and ensure the proxy overwrites forwarded headers.
What should I test after deployment?
Test the private health URL, supervisor status and logs, the public HTTPS health URL, a Socket.IO connect event, an idle connection beyond the heartbeat interval, and recovery after a controlled VPS reboot.
The Bottom Line
For a dependable single-VPS deployment, install Express and Socket.IO locally, attach Socket.IO to the same Node HTTP server as Express, bind Node to 127.0.0.1, and proxy it through Nginx with HTTP/1.1 upgrade headers and a read timeout above the heartbeat period. Run one supervisor—PM2 or systemd—configure Express proxy trust to match the real topology, and verify health, WebSocket connectivity, idle stability, and reboot recovery before scaling to multiple workers.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

