OpenVibe.Live/Docs
Source on GitHub

Deploying OpenVibe.Live#

Live deploys with ovhost deploy live (OpenVibe.Host, /usr/local/bin/ovhost, strategy release-layout; roadmap WS-N task 11). deploy/scripts/deploy.sh is a thin wrapper that maps its old flags onto ovhost, so the commands stay the same:

cd /opt/openvibe.live/current
sudo deploy/scripts/deploy.sh              # ovhost deploy live: origin/main if it moved
sudo deploy/scripts/deploy.sh --wait-idle  # ovhost deploy live --wait-idle: hold a restart until nobody is live
sudo deploy/scripts/deploy.sh --restart    # ovhost deploy live --restart
sudo deploy/scripts/deploy.sh --rollback   # ovhost rollback live: the release the current one replaced
DRY_RUN=1 deploy/scripts/deploy.sh         # ovhost plan live: print the plan only

The wrapper checks ovhost capabilities live (deploy API 1, strategy release-layout, managed). If ovhost is unavailable or incompatible, the wrapper exits 1. OVHOST=<path> picks another ovhost. --force has different semantics in ovhost, so the wrapper refuses it; run sudo ovhost deploy live --force explicitly if needed. ovhost records each attempt in its release log (ovhost releases live) and refuses a frozen service (ovhost freeze, exit 6).

What each kind of change costs#

Files changedActionInterruption
docs/, public/ (JS, CSS, HTML, fragments, images)files switched in place; the running server re-reads documents and re-hashes assets within ~2 snone — no restart
README, tests, scriptsfiles switchednone
server/, vendor/, package.json dependenciesrestart, gated on GET /api/readynew HTTP connections queue on the systemd socket; established WebSocket, WHIP, WebRTC and RTMP sessions drop and reconnect
package-lock.jsonnpm ci before anything is interrupted (release layout: into the new release)as server
migrations/a database backup (ovhost backup live), then restart; the release applies them at bootas server
deploy/systemd/units installed, daemon-reload, restartas server
deploy/nginx/not installed — the live nginx config is managed separately (see below); the script prints a noticenone

Socket activation (deploy/systemd/openvibe-live.socket) protects new HTTP connections during a restart. It does not keep existing WebSockets, RTMP publishers, WHIP sessions or mediasoup UDP flows. Clients reconnect with jittered backoff and show "OpenVibe is updating" / "Reconnected" (ovConnectionPill in public/js/app.js). Use --wait-idle when someone is streaming.

Layouts#

Release layout (production): deploy from /opt/openvibe.live/current. The release directories are root-owned, so the manifest takes the release id from the directory name (<time>-<sha8>), and the host inventory runs git for Live as root (owner: root, runAs: ubuntu for drills).

/opt/openvibe.live/repo                 git clone used to create releases
/opt/openvibe.live/releases/<time>-<sha> worktree + its own node_modules + data -> ../../shared/data
/opt/openvibe.live/current              -> releases/<id>   (atomic rename)
/opt/openvibe.live/shared/data          uploads and runtime files (never copied or reset)

test/deploy-wrapper.test.js checks the wrapper's flag mapping and errors. ovhost's own tests (OpenVibe.Host test/strategy-release-layout.test.js) cover release behavior and the socket rule.

Assets and caching#

nginx#

deploy/nginx/openvibe.live.conf is what production runs; it was identical to /etc/nginx/sites-enabled/openvibe.live.conf on 2026-09-17. OpenVibe.Network's generator (server/deploy/nginx-generator.js) now carries the same WHIP/ingest hostnames, connection budgets, static cache, gzip and log format for Live, enforced by that repo's test/nginx-generator-live.test.js. Apply nginx changes by hand: copy the file, nginx -t, systemctl reload nginx.

Restore drills#

ovhost drill live (OpenVibe.Host, docs/restore-drills.md) restores the latest backup of ov_live into a database of its own and starts a second Live from this checkout on 127.0.0.1:13000 with LIVE_DRILL=1, DATABASE_URL and DATABASE_DIRECT_URL on the copy and DATA_DIR in a directory of its own (without a database URL it uses an embedded PGlite database under DATA_DIR). In that mode (server/drill.js) Live:

test/drill-mode.test.js boots the real server that way and checks each point.

Checks#

npm test                         # unit, security, migrations, size budgets
BASE=http://127.0.0.1:3000 npm run test:browser   # needs a running server and Chrome
deploy/scripts/post-deploy-check.sh                # on the host after a deploy

N-1: the previous release against this one#

For 24 hours after a deploy (ADR-016) open tabs run the previous release's client against the new server, and a previous-release process may still be working on the database the new one migrated. test/n-1.test.js (in npm test, so in CI) checks compatibility using fixtures recorded from the release in production:

After each deploy, record the release now in production as the next release's N-1 and commit it:

npm run n-1:record               # from HEAD (the deployed commit)
npm run n-1:record -- <sha>      # or the release production's /release.json names

This page is rendered from docs/deploy.md in the OpenVibe.Live repository. Found a mistake? Edit it there.