Deploy WebSocket | Node Server Sharing One Port with HTTP
WebSocket server on Node and TypeScript, HTTP health check on the same port
WebSocket
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.
| Variable | Why |
|---|---|
| PORT | HTTP and WebSocket share it - the platform routes one port |
| HEARTBEAT_MS | Ping 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
WebSocket
ak40u/websocket-railway-starter