How to Self-Host RustDesk (Remote Desktop Support for Family and Clients, Without TeamViewer)

"Can you look at my computer?" — from a parent, a friend, a customer. TeamViewer and AnyDesk work until they decide you're "commercial" and start charging, and every session passes through their servers. RustDesk is an open-source remote desktop whose server side is two small programs you run yourself: an ID server that introduces the two ends, and a relay for when they can't connect directly. Clients for Windows, Mac, Linux, iOS and Android, with your server's address and public key built in, so the person you're helping installs one thing and reads you a number.
Quick reference
| Piece | What |
|---|---|
| Containers | rustdesk/rustdesk-server — hbbs (ID/rendezvous) and hbbr (relay) |
| Ports | 21115–21117/tcp, 21116/udp (hbbs); 21117/tcp (hbbr); 21118–21119 for web clients |
| Public name | rd.example.com → your IP (dynamic DNS, 48) with the ports forwarded |
| Key | ./data/id_ed25519.pub — clients must present it |
| Client config | ID server rd.example.com, Key — or a pre-built client |
| Permanent access | the unattended password on the remote machine, set by its owner |
1. The compose file
mkdir -p ~/docker/rustdesk/data && cd ~/docker/rustdesk
nano compose.yaml
services:
hbbs:
image: rustdesk/rustdesk-server:latest
container_name: hbbs
command: hbbs -r rd.example.com:21117
ports:
- "21115:21115"
- "21116:21116"
- "21116:21116/udp"
- "21118:21118"
volumes:
- ./data:/root
depends_on: [hbbr]
restart: unless-stopped
hbbr:
image: rustdesk/rustdesk-server:latest
container_name: hbbr
command: hbbr
ports:
- "21117:21117"
- "21119:21119"
volumes:
- ./data:/root
restart: unless-stopped
docker compose up -d
cat data/id_ed25519.pub
That public key is what clients must know; it stops anyone else using your relay.
2. Open the ports
sudo ufw allow 21115:21119/tcp
sudo ufw allow 21116/udp
On the router, forward 21115–21119 TCP and 21116 UDP to the server. rd.example.com is a DuckDNS or Cloudflare name (48) pointing at your home IP (not proxied — these aren't HTTP). Behind CGNAT (47), run these two containers on a cheap VPS instead; they're tiny.
Lock relay use to clients with the key: hbbs -r rd.example.com:21117 -k _ makes the key mandatory.
3. Configure a client
Install RustDesk on your own PC. Settings → Network → ID/Relay server: ID server rd.example.com, Relay server rd.example.com, Key = the public key. Your ID appears; it's now registered with your hbbs.
The other person does the same — or, better, you give them a pre-configured client: RustDesk builds one from the download page if you rename the installer rustdesk-host=rd.example.com,key=.exe, so they install and it's already pointed at your server. For a parent, that's the whole setup: install, read out the 9-digit ID and the password shown.
4. Connect
Type their ID, enter the one-time password they read you (or the permanent unattended password they set under Settings → Security on their machine for recurring help). Their screen appears; file transfer, clipboard and chat are in the toolbar. They see a notification that you're connected and can end it at any time — it's their machine, and consent is the point.
Direct connections (both ends behind friendly NATs) skip the relay; otherwise traffic goes through hbbr on your box. Either way, nobody else's servers.
5. For a small business
Unattended access to a handful of client machines (with their written agreement): each gets the pre-built client and a strong permanent password; you keep an address book in the RustDesk client (or RustDesk's Pro server for a web console and user accounts, if it grows). Sessions can be recorded for the audit trail; 2FA on your own RustDesk login. Log who you connected to and when (BookStack, 88) — it's good practice and clients appreciate it.
6. Behind the VPN instead
If everyone you help is family on your Tailscale/WireGuard (33, 47), skip the port forwards entirely: the ID server listens on the LAN, clients connect over the VPN, and nothing is public. Same containers, no router changes.
Troubleshooting
"Not ready" / ID not registering. 21116/udp isn't reaching hbbs — the router forward, or UFW. nmap -sU -p 21116 from outside (171).
Connects but black screen / very slow. Relay path on a slow upload; try "direct" in connection settings, or reduce quality. Wayland on a Linux host needs the Wayland-capable build.
"Key mismatch". The client's key doesn't match id_ed25519.pub — common after you recreated ./data. Back that folder up.
Works at home, not from outside. Dynamic DNS pointing at an old IP (48), or CGNAT — a VPS for hbbs/hbbr.
Wrapping up
Two containers, five ports, one public key. A client you can hand to anyone with your server built in, sessions that run between the two machines or through your relay, and a remote-support tool that will never email you about a licence.
