rustdesk docker: containerized RustDesk server guide

You're trying to self‑host RustDesk without wrestling with manual builds, dependency hell, or brittle VM images. This guide shows how to run a production‑ready RustDesk server stack with Docker and Docker Compose, so you can manage updates, backups and scaling like an ops person — not a hobbyist.
You're trying to self‑host RustDesk without wrestling with manual builds, dependency hell, or brittle VM images. This guide shows how to run a production‑ready RustDesk server stack with Docker and Docker Compose, so you can manage updates, backups and scaling like an ops person — not a hobbyist.
Why use docker for RustDesk
Containers give two immediate wins for a self‑hosted remote‑access stack: reproducible deployments and isolation. Instead of compiling hbbs/hbbr locally or running platform‑specific packages, you pull a Docker image, mount a persistent volume and start. That simplifies upgrades, CI/CD and host migrations. If you already run other services in containers (NGINX, certbot, monitoring), adding RustDesk this way keeps your stack consistent.
When not to containerize: if you need custom patched binaries or deep kernel integration for very high‑performance relay, a native install might be preferable. Also, if you need an officially supported enterprise SLA from the vendor, check whether containers are supported by that vendor.
RustDesk server components — brief overview
RustDesk splits the server role into at least two pieces:
- hbbs — the ID/signaling server. It handles registration and rendezvous for clients.
- hbbr — the relay server (if NAT traversal fails). It relays traffic between peers.
In production you typically run both. A single lightweight host can run both services; larger deployments separate them, put hbbr instances behind a load balancer, and add autoscaling for relay capacity.
Quickstart: example Docker Compose deployment
Prerequisites: Ubuntu 22.04 LTS (or any Linux with Docker Engine 20.10+), Docker Compose v2.x, a domain name (example: rustdesk.example.com). Allocate at least 512 MB RAM for a tiny test server; 1 GB+ recommended for a relay that will handle multiple active sessions.
Below is a practical Docker Compose example that runs hbbs and hbbr in separate services, mounts persistent data, and publishes the standard RustDesk ports. Before you run it, check the official rustdesk/rustdesk-server image tags for the latest stable tag and replace rustdesk/rustdesk-server:latest if you want a pinned version.
version: '3.8'
services:
hbbs:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbs
command: ["hbbs", "--listen", "0.0.0.0:21115"]
ports:
- "21115:21115/tcp"
- "21115:21115/udp"
volumes:
- ./data/hbbs:/data
restart: unless-stopped
hbbr:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbr
command: ["hbbr", "--listen", "0.0.0.0:21116", "--relay", "0.0.0.0:21116"]
ports:
- "21116:21116/tcp"
- "21116:21116/udp"
volumes:
- ./data/hbbr:/data
restart: unless-stopped
networks:
default:
external: falseExplanation:
- We run hbbs on TCP/UDP port 21115 and hbbr on 21116 — these are the common defaults for RustDesk server builds. Confirm the port mapping for the image you use (some community builds use different defaults).
- Persistent volumes
./data/hbbsand./data/hbbrkeep your registration and relay data across restarts. - Use
restart: unless-stoppedfor basic resilience; for production, tie into your orchestration platform's restart policies.
Expose securely: TLS, reverse proxy and firewall
RustDesk's signaling and relay traffic can be protected by TLS and standard firewall rules. There are two common approaches:
- Direct TLS with a proxy in front of hbbs (recommended for web-level cert management).
- Keep hbbr as a raw TCP/UDP relay and secure the host network (use ufw/nftables) while securing hbbs with TLS.
Most setups use NGINX or Traefik to terminate TLS and forward traffic to hbbs. Example NGINX server block to terminate TLS for rustdesk.example.com:
server {
listen 443 ssl;
server_name rustdesk.example.com;
ssl_certificate /etc/letsencrypt/live/rustdesk.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rustdesk.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:21115;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# Optional: redirect http to https
server {
listen 80;
server_name rustdesk.example.com;
return 301 https://$host$request_uri;
}Use certbot (Let's Encrypt) or your CA to get certs. If your relay (hbbr) runs on public UDP/TCP, expose those ports directly with the firewall limited to the IP ranges you expect, or put the relay nodes in a private subnet behind a load balancer.
DNS, clients and NAT traversal
Point a DNS A record (e.g., rustdesk.example.com) to your server's public IP. In the RustDesk client, set the server address to that domain (for ID and relay lookup). Clients use the ID server for rendezvous; if both clients are behind restrictive NAT, hbbr will relay the session through your relay server.
If you control client machines in a LAN, you can run an internal DNS or distribute a configuration file that points clients to the internal IP of hbbs for faster local connections.
Scaling and resource guidance
How much CPU/RAM does a relay need? It depends on concurrent sessions and session type:
- Small test server: 1 vCPU, 512 MB RAM — handful of idle connections.
- Production relay (light usage): 2 vCPU, 1–2 GB RAM — dozens of concurrent sessions.
- High throughput relay: 4+ vCPU, 4+ GB RAM and network capacity matching expected bandwidth (e.g., 100+ Mbps).
We recommend autoscaling hbbr instances behind a load balancer if you expect spikes (media heavy remote control, screen sharing). Use container orchestration (Kubernetes, Docker Swarm) or simple horizontal scaling with a TCP/UDP load balancer (haproxy, cloud LB) that preserves client IPs.
Backups, updates and version pinning
Always mount persistent volumes for data and back them up regularly. A minimal backup script:
# daily-backup.sh
TIMESTAMP=$(date +%F)
mkdir -p /backups/rustdesk/$TIMESTAMP
rsync -a ./data /backups/rustdesk/$TIMESTAMP/
# rotate: keep 14 days
find /backups/rustdesk -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;For updates, pin the Docker image with a tag instead of :latest. Run a staging test when bumping the server image. Example workflow:
- Pull new image:
docker pull rustdesk/rustdesk-server:1.3.0(example). - Spin up a test container with the same volumes and run smoke tests.
- Schedule a maintenance window and replace the containers on production host(s).
Troubleshooting and common pitfalls
Start with logs: docker logs rustdesk-hbbs and docker logs rustdesk-hbbr. Typical issues:
- Clients cannot register: check hbbs is reachable on the domain and TLS is valid.
- Sessions fall back to relay but performance is poor: inspect relay host CPU/memory and network. Relay packets are typically UDP; ensure UDP is allowed through your firewall and on your cloud security group.
- Clients show mismatched versions: use matched or compatible RustDesk client/server versions. If you pin your server image, ensure clients are not using deprecated protocol features.
If NAT traversal fails consistently for many clients, the problem is usually symmetric NAT or enterprise firewalls. In those cases, rely on hbbr relays and monitor latency/throughput to ensure acceptable UX.
Security considerations
Self‑hosting shifts responsibility to you. Key steps:
- Terminate TLS at a reverse proxy and use strong ciphers. Obtain certs from Let's Encrypt or a trusted CA.
- Harden the host: run only necessary ports, enable automatic security updates on the OS, and use a firewall (ufw/nftables).
- Limit access to admin interfaces and monitor logs for brute force attempts. Consider network segmentation; place relay nodes in a separate subnet if possible.
If you want a broader discussion of locking down remote access, see our pieces on remote desktop security and the practical tradeoffs in self‑hosted remote desktop.
When a managed vendor is better
Self‑hosting with docker gives control and privacy, but if you need a fully managed SLA, official enterprise features (user management, centralized billing), or turn‑key Windows AD integration, commercial vendors like TeamViewer or AnyDesk may be better choices. Be honest about the tradeoffs: self‑hosted saves on per‑seat recurring fees and gives data locality, but costs operations time to maintain, monitor and secure.
Next steps and references
Checklist to go from lab to production:
- Pick a host with Docker Engine 20.10+ and Docker Compose v2.x.
- Create persistent volumes and a daily backup job.
- Pin the server image and validate updates in staging.
- Terminate TLS with NGINX/Traefik and obtain certs from Let's Encrypt.
- Monitor the relay hosts and scale hbbr when CPU or bandwidth hits health thresholds.
Want a clean download to compare side‑by‑side with a container approach? Grab Tenvo’s binaries or installers at /download and check our /pricing page for deployment options. If you'd rather follow a broader remote access setup, our remote access setup guide covers network, auth and usability topics across tools.
Running RustDesk under Docker is a solid, maintainable approach for most self‑hosters: it simplifies upgrades and meshes well with existing container infra. If you need a copy of the compose file or help adapting this to Kubernetes, drop back and I’ll provide a K8s manifest and a Helm chart example.
Ready to try it? Download the necessary clients or test images from /download and get your containerized RustDesk server running today.
Ready to try it yourself?
Free for 30 devices, no credit card. Up and connected in two minutes.