Docker - UNITRONIX/BetterDesk GitHub Wiki
Docker Deployment
BetterDesk offers multiple Docker deployment options.
Quick Start (Pre-built Images)
The fastest way to get started — no build required:
curl -fsSL https://raw.githubusercontent.com/UNITRONIX/Rustdesk-FreeConsole/main/docker-compose.quick.yml \
-o docker-compose.yml
docker compose up -d
Default access:
- Web Console: http://localhost:5000
- Default admin:
admin/ check container logs for password
# View generated admin password
docker compose logs console | grep "Admin password"
Deployment Options
Option 1: Multi-Container (Recommended for Production)
Separate containers for each service:
git clone https://github.com/UNITRONIX/Rustdesk-FreeConsole.git
cd Rustdesk-FreeConsole
docker compose up -d --build
docker-compose.yml runs 3 containers:
betterdesk-server— Go server (signal + relay + API)betterdesk-console— Node.js web console- Shared volume for database and keys
Option 2: Single Container
All services in one container (simpler, good for testing):
docker compose -f docker-compose.single.yml up -d --build
Uses supervisord to run Go server + Node.js console in a single container.
⚠️ Note: In single-container mode,
SIGNAL_PORT=21116is set explicitly to prevent conflict withPORT=5000(used by Node.js).
Option 3: Interactive Docker Script
./betterdesk-docker.sh
Interactive menu with:
- New installation
- Update
- Migrate from existing RustDesk Docker
- Database migration (SQLite ↔ PostgreSQL)
Ports
Expose the following ports in your Docker configuration:
ports:
- "21114:21114" # Go API
- "21115:21115" # NAT test
- "21116:21116" # Signal (TCP)
- "21116:21116/udp" # Signal (UDP)
- "21117:21117" # Relay
- "21118:21118" # WS Signal
- "21119:21119" # WS Relay
- "21121:21121" # Client API (Node.js)
- "5000:5000" # Web Console
Volumes
Data Persistence
volumes:
betterdesk-data:
driver: local
Persist these paths:
/data/— Database files, keys, API key/opt/BetterDeskConsole/data/— Console database, auth
Important Files in Volume
| File | Description |
|---|---|
id_ed25519 |
Server private key |
id_ed25519.pub |
Server public key |
db_v2.sqlite3 |
Go server database |
.api_key |
API authentication key |
auth.db |
Console user database |
⚠️ Never delete
id_ed25519— all connected clients use this key. Regenerating it requires reconfiguring every client.
PostgreSQL with Docker
Add PostgreSQL Container
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: betterdesk
POSTGRES_PASSWORD: your-secure-password
POSTGRES_DB: betterdesk
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U betterdesk"]
interval: 5s
timeout: 5s
retries: 5
server:
# ... existing config ...
environment:
DB_URL: postgres://betterdesk:your-secure-password@postgres:5432/betterdesk?sslmode=disable
depends_on:
postgres:
condition: service_healthy
console:
# ... existing config ...
environment:
DB_TYPE: postgresql
DATABASE_URL: postgres://betterdesk:your-secure-password@postgres:5432/betterdesk?sslmode=disable
volumes:
postgres-data:
Environment Variables
Go Server Container
| Variable | Default | Description |
|---|---|---|
SIGNAL_PORT |
21116 |
Signal server port |
RELAY_PORT |
21117 |
Relay server port |
DB_URL |
db_v2.sqlite3 |
Database path or PostgreSQL DSN |
RELAY_SERVERS |
auto-detected | Relay server addresses |
API_KEY |
auto-generated | API authentication key |
CDAP_ENABLED |
N |
Enable CDAP gateway |
Node.js Console Container
| Variable | Default | Description |
|---|---|---|
PORT |
5000 |
Web console port |
BETTERDESK_API_URL |
http://server:21114/api |
Go API URL |
API_KEY |
from file | API key |
DB_TYPE |
sqlite |
Database type |
DATABASE_URL |
(empty) | PostgreSQL DSN |
SESSION_SECRET |
auto-generated | Session encryption key |
Building Images
Build All Images
docker compose build
Build Individual Images
# Go server
docker build -f Dockerfile.server -t betterdesk-server .
# Node.js console
docker build -f Dockerfile.console -t betterdesk-console .
# Single container (all-in-one)
docker build -t betterdesk .
Monitoring
View Logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f server
docker compose logs -f console
Health Check
# Server health
curl http://localhost:21114/api/health
# Console health
curl http://localhost:5000
Container Status
docker compose ps
Migration from RustDesk Docker
If you have an existing RustDesk Docker deployment:
./betterdesk-docker.sh
# Choose option M — Migrate from RustDesk Docker
The migration:
- Stops existing RustDesk containers
- Copies
db_v2.sqlite3andid_ed25519keys - Starts BetterDesk containers
- Verifies data migration
See Migration for more details.
Troubleshooting
GHCR "denied" Error
If pre-built images from ghcr.io are not available:
# Option 1: Build locally
docker compose up -d --build
# Option 2: Authenticate with GitHub
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
DNS Resolution Failures During Build
Docker build on some hosts (AlmaLinux, CentOS) may fail DNS resolution. The Dockerfiles include retry logic for apk add commands. If issues persist:
# Add DNS to Docker daemon
echo '{"dns": ["8.8.8.8", "8.8.4.4"]}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
SELinux Volume Mount Issues
On RHEL/CentOS with SELinux:
# Option 1: Named volumes (recommended)
# Already used in docker-compose.yml
# Option 2: :z flag for bind mounts
volumes:
- ./data:/data:z
# Option 3: Set context
sudo chcon -Rt svirt_sandbox_file_t ./data
Port 5000 Conflict (Single Container)
If both Go server and Node.js try to bind port 5000, ensure SIGNAL_PORT=21116 is set in the Go server environment. This is set automatically in supervisord.conf and entrypoint.sh.