Skip to content
TraceMote
Self-hosting

One host, six ports, no phone-home

Run the rendezvous server, the relay, the auth backend and the console yourself, and the client only ever talks to machines you own. If you would rather not, the managed plans run this same stack for you.

server side
# everything server-side, on one host
docker compose up -d

#   mongo   internal only, never published
#   api     :21114   the client's API + the console's backend
#   hbbs    :21116   rendezvous, tcp + udp
#   hbbr    :21117   relay
#   web     behind your TLS terminator

# seed the first administrator, then log in to the console
docker compose exec api node dist/scripts/seed-admin.js \
  --email you@example.com
dns & tls
# DNS — three names, one host is fine to start
rustdesk.example.com  A  203.0.113.10   # rendezvous + relay + api
api.example.com       A  203.0.113.10   # TLS, proxied to :21114
console.example.com   A  203.0.113.10   # TLS, the console

# TLS terminates at your proxy, for the API and the console only.
# Rendezvous and relay are not HTTP and are not proxied.
Sizing

It is smaller than you expect

The rendezvous server brokers introductions; it does not carry sessions. The relay only carries the fallback path, and how much that costs depends entirely on your NAT situation.

2 vCPU / 2 GB

Comfortable for a few hundred devices, including MongoDB on the same host.

Bandwidth follows the relay

Direct sessions cost the server nothing. Budget relay bandwidth for the share of peers that cannot punch a hole.

One region is usually enough

Latency that matters is peer to peer. The rendezvous round trip happens once, at the start.

Ports

What to open, and what to keep shut

PortProtocolPurposeExposure
21114TCP / HTTPAuth API. The client derives this as rendezvous port − 2 unless api-server is set.Public (put TLS in front of it)
21115TCPNAT-type test listener — and, from loopback, the runtime console.Not for the internet
21116TCP + UDPRendezvous. UDP registers and keeps alive, TCP carries punch-hole and relay signalling.Public, both protocols
21117TCPRelay fallback for peers that cannot punch a hole.Public
21118TCPWebSocket rendezvous; also the client's direct-access port.Public if you need web clients
21119TCPWebSocket relay.Public if you need web clients
Traps

Four mistakes that fail silently

Every one of these produces a working-looking deployment with a broken path and no error anywhere. They are worth reading before you start, not after.

01

Give the relay the address clients dial

Never a container name, and never loopback. A relay reached on a loopback address answers with its runtime console instead of relaying, so you get working direct connections and every relayed session hanging — with nothing in either log.

02

Do not run it behind a routing mesh that source-NATs

If the rendezvous server sees one internal address for your whole fleet, it hands that address out as the punch-hole target. Hole punching stops working, everything falls back to the relay, and nothing logs an error.

03

Publish the API on 21114 until your builds are branded

A client that has not been told otherwise does not discover the API — it computes it from the rendezvous host, port minus two, over plain HTTP. Once you ship a branded build with the API baked in, that constraint is gone.

04

Keep the server key backed up

It is the single most valuable file on the host. Lose it and every client in the fleet has to be re-keyed by hand.

Before you go live

The checklist

TLS in front of the API and the console, sharing a registrable domain
Port 21115 firewalled off — it answers online-status queries to anyone
The relay started with an explicit key; without one it compares nothing
Break-glass keys generated, with only the public half on the server
MongoDB on a private network with no published port
Backups of the rendezvous key, the database, and your signing key

Upgrades

Server images are versioned and the client protocol is upstream’s, so a newer server keeps talking to older clients. Upgrade the server first, then roll clients at your own pace.

Backups

Three things: the rendezvous server’s key, the MongoDB volume, and the private half of your configuration signing key. The first cannot be regenerated without re-keying every client; the third cannot be regenerated at all without reissuing every branded build.

Monitoring

The API exposes a health endpoint. The two signals worth alerting on are authorization decisions failing — which means connections are being refused — and any unexpired break-glass capability, which the console banners anyway.

Get started

Stand it up in an afternoon

Compose file, environment template and the deployment guide are all in the repository — including the parts that were wrong the first time and got fixed.