openvibers/openvibe.live Commits

Support systemd socket activation so a restart stops returning 502s

OP OpenVibers committed 16 Sept 2026 · d55b8f2072 · 1 file, +11 −2

nginx proxies straight to this process, so every restart refuses connections for the second or
so it takes to boot, and anyone loading the site during a deploy gets a Cloudflare 502. That has
happened three times today.

When a systemd .socket unit owns the listening socket it passes it in as fd 3, and connections
that arrive mid-restart queue in the kernel instead of being refused — the request is slow
instead of broken. This detects that handoff and listens on the descriptor; with no socket unit
present it is an ordinary listen on the configured port, so running it by hand or in dev is
unchanged.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01CMxJm1dB8rdsaMSgNjVa82

Changes

ddiff --git a/server/index.js b/server/index.js
iindex 026c79e5..2473fb95 100644
---- a/server/index.js
++++ b/server/index.js
@@@ -1075,8 +1075,17 @@ async function start() {
// 6f. VOD storage/offload is owned by OpenVibe.Media now — nothing to start here.
-- // 7. Start HTTP server
-- server.listen(config.port, config.host, () => {
++ // 7. Start HTTP server.
++ //
++ // Zero-downtime restarts: when systemd owns the listening socket (a .socket unit with
++ // Accept=no) it hands it to us as file descriptor 3. Connections that arrive while we are
++ // restarting then wait in the kernel's accept queue instead of being refused, so a deploy
++ // costs a handful of slow requests rather than a wall of 502s for everyone mid-page.
++ // Without the socket unit this is a normal listen on the configured port, so the code is
++ // identical to run by hand, in dev, or on a box that has not been switched over.
++ const socketActivated = process.env.LISTEN_FDS === '1' && Number(process.env.LISTEN_PID) === process.pid;
++ if (socketActivated) console.log('[Server] socket-activated: listening on the socket systemd handed us (fd 3)');
++ server.listen(socketActivated ? { fd: 3 } : { port: config.port, host: config.host }, () => {
console.log('');
console.log(`[Server] HTTP server: http://${config.host}:${config.port}`);
console.log(`[Server] WebSocket: ws://${config.host}:${config.port}/ws/chat`);