Railway

Deploy WebSocket | Node Server Sharing One Port with HTTP

WebSocket server on Node and TypeScript, HTTP health check on the same port

Deploy WebSocket | Node Server Sharing One Port with HTTP

Just deployed

Deploy and Host a WebSocket Server on Railway

A WebSocket server on Node 24 and TypeScript, sharing one port with an HTTP endpoint - which is what makes it deployable.

About Hosting WebSockets

The Node.js WebSocket template on Railway builds from a repository last updated in September 2024, with esbuild 0.17 and a pnpm bundling pipeline. Under four deployments in ten come up.

The deeper problem is structural: it serves WebSockets and nothing else. A platform health check speaks plain HTTP, so a WebSocket-only process has nothing to answer it with - the deployment is marked unhealthy while working perfectly, or you switch the check off and lose the signal entirely.

Here the WebSocket server is attached to a Node HTTP server. The same port answers GET /health, serves a browser test client, and upgrades connections to WebSocket. On a platform that routes one port per service, that is the shape the app has to have.

Common Use Cases

  • Live updates pushed to a browser - notifications, presence, progress
  • A chat or collaboration back end
  • A control channel for a dashboard, where polling would be wasteful

Dependencies for WebSocket Hosting

  • Nothing. One service, no database.

Deployment Dependencies

Implementation Details

Open the domain: the page connects over wss:// by itself. Open it in a second tab and the two exchange messages. GET /health reports the current connection count, which is a genuinely useful thing to have on a socket server.

Three details worth keeping if you rewrite this:

  • Heartbeat. Clients disappear without closing the socket - a laptop lid, a dropped mobile connection. Without a ping/pong sweep the server holds those sockets forever and the connection count drifts away from reality.
  • Payloads are capped at 4 KB before broadcast, so one client cannot push arbitrary volume at everyone else.
  • Shutdown closes sockets with code 1001 before the process exits, so clients reconnect immediately instead of waiting for a timeout to notice.
VariableWhy
PORTHTTP and WebSocket share it - the platform routes one port
HEARTBEAT_MSPing interval, default 30000

Scaling note

Broadcast is in-process: a message reaches the clients connected to this instance. With more than one replica you need a shared bus - Redis pub/sub is the usual answer - to fan messages out across them.

Why Deploy WebSockets on Railway?

TLS on the domain means wss:// works with no extra configuration, and because the health check shares the port, the platform can actually tell whether your socket server is alive.


Template Content

More templates in this category

View Template
open-excalidraw
Self-hostable collaborative drawing built on Excalidraw

Prateek Mohanty
1
View Template
caring-vibrancy
Deploy and Host caring-vibrancy with Railway

5
View Template
Flask WebSocket Chat
Single file, realtime multi-user websocket chat using flask-socketio

Clement Ochieng
3