Run the whole thing on your own box — the workspace, the database and the relay. Nothing leaves your network unless you allow it.
Chat, files, projects, tracked hours and work-diary screenshots live in a SQLite file on your server. Take a copy whenever you like; it is one file.
A Node.js server (signalling + workspace API + admin panel) and a coturn STUN/TURN relay. Both run comfortably on a 1 vCPU VPS.
Point the desktop and Android apps at your server URL — no separate build, no fork, no per-seat call home.
One Node process does four jobs, so there is one thing to keep alive rather than four:
Introduces two devices to each other by their 9-digit IDs and gets out of the way. Screens, keystrokes, files and meeting media then travel directly between the peers, encrypted with DTLS-SRTP. The server cannot read them and never stores them.
Accounts, chat, uploads, projects and tasks, meetings, WorkTrack hours, timesheets and invoices. This is the part that is stored — on your disk, so history and search work from any device.
At /admin, behind a token. Workspaces and their plans, accounts, licence keys, installer download counts, and the ability to block a specific machine.
Drop your builds into the data directory and the server serves and counts them at /download/win, /mac, /linux and /android. No third-party analytics needed to answer “how many downloads?”.
On a fresh Ubuntu server with Node.js 18+ installed:
# 1. the server
git clone https://example.com/remotedesk.git
cd remotedesk/server
npm install # builds better-sqlite3 for THIS machine
export RD_DATA_DIR=/var/lib/officedesk
export RD_LICENSE_SECRET="$(openssl rand -hex 32)" # keep this; it signs licence keys
export RD_ADMIN_TOKEN="$(openssl rand -hex 24)" # unset = /admin stays off
export RD_PUBLIC_URL=https://desk.example.com
node signaling.js # listens on :9000
# 2. STUN + TURN relay (coturn)
sudo apt install coturn
sudo nano /etc/turnserver.conf # realm, static-auth-secret, external-ip
sudo systemctl enable --now coturn
# 3. point the clients at your server
# Settings -> Server URL
wss://desk.example.com
The database is created and migrated automatically on first start — there is no separate schema step. Upgrading is the same command; pending migrations run at boot.
One thing to get right when you deploy: build node_modules on the server. better-sqlite3 is a native module, so copying a Windows or macOS node_modules to a Linux box gives you a process that exits before it ever listens.
| Service | Port | Protocol |
|---|---|---|
| Signalling + API + admin | 9000 (443 via proxy) | TCP / TLS |
| STUN & TURN | 3478 | TCP + UDP |
| TURN over TLS | 5349 | TCP |
| TURN relay range | 49152-65535 | UDP |
Run coturn and you also get your own STUN. The apps do not need a public STUN service, so no address discovery goes to a third party.
| Variable | What it does |
|---|---|
RD_DATA_DIR | Database, uploads, installers |
RD_LICENSE_SECRET | Signs licence keys — unset means they die on restart |
RD_ADMIN_TOKEN | Unlocks /admin; unset keeps it off |
RD_TURN_SECRET | Must match coturn’s static-auth-secret |
RD_PUBLIC_URL | Base URL used in invite links |
RD_WORKSPACE_TRIAL_DAYS | Workspace trial length (default 7) |
PORT / HOST | Default 9000 / 0.0.0.0 |
RD_DATA_DIR. That single directory is your entire workspace.Self-hosting is the deployment we recommend to anyone with a confidentiality obligation to their own clients — and to anyone enabling WorkTrack, since employee monitoring data is far easier to defend when it never left your building.
Download Office Remote Desk and connect your first device in under a minute.