mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 17:45:42 +00:00
43e0b6f40a
Expose global connection strategy in the web panel with systemd/Docker persistence, extend server health diagnostics, enforce org network policy in the signal handler, and document when relay fallback is expected vs misconfiguration.
170 lines
5.3 KiB
YAML
170 lines
5.3 KiB
YAML
# BetterDesk Console - Docker Compose Setup
|
|
# Architecture: Go server (single binary) + Node.js web console
|
|
#
|
|
# ============================================================================
|
|
# QUICK START (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
|
|
#
|
|
# BUILD FROM SOURCE (this file):
|
|
# docker compose build && docker compose up -d
|
|
# ============================================================================
|
|
#
|
|
# The Go server replaces separate hbbs/hbbr — it handles signal, relay,
|
|
# and HTTP API in a single process.
|
|
|
|
services:
|
|
# BetterDesk Server (Go) — replaces hbbs + hbbr
|
|
# Single binary: signal (21116), relay (21117), API (21114), NAT test (21115)
|
|
server:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.server
|
|
image: betterdesk-server:local
|
|
pull_policy: never
|
|
container_name: betterdesk-server
|
|
hostname: betterdesk-server
|
|
command: ["/usr/local/bin/betterdesk-server", "-mode", "all", "-api-port", "21114", "-key-file", "/opt/rustdesk/id_ed25519"]
|
|
ports:
|
|
- "21114:21114" # Go HTTP API (default — direct client + REST)
|
|
- "21115:21115" # NAT type test
|
|
- "21116:21116/tcp" # Signal TCP
|
|
- "21116:21116/udp" # Signal UDP
|
|
- "21117:21117" # Relay TCP
|
|
- "21118:21118" # WebSocket Signal
|
|
- "21119:21119" # WebSocket Relay
|
|
volumes:
|
|
- rustdesk-data:/opt/rustdesk
|
|
environment:
|
|
- ENCRYPTED_ONLY=1
|
|
- DB_URL=${DB_URL:-/opt/rustdesk/db_v2.sqlite3}
|
|
- SIGNAL_RATE_LIMIT_PER_IP=${SIGNAL_RATE_LIMIT_PER_IP:-20}
|
|
- P2P_FIRST=${P2P_FIRST:-Y}
|
|
- ALWAYS_USE_RELAY=${ALWAYS_USE_RELAY:-N}
|
|
- P2P_FALLBACK_MS=${P2P_FALLBACK_MS:-2000}
|
|
- SAME_NAT_RELAY=${SAME_NAT_RELAY:-Y}
|
|
# Enrollment policy. Fresh volumes default to "managed" (operator approves
|
|
# new devices); pre-existing volumes keep their current mode. Set to
|
|
# "open", "managed", or "locked" to override.
|
|
- ENROLLMENT_MODE=${ENROLLMENT_MODE:-}
|
|
networks:
|
|
- betterdesk-net
|
|
restart: unless-stopped
|
|
# SECURITY (audit fix L-02, 2026-04-10): drop all capabilities except
|
|
# those needed by the entrypoint to chown volumes + su-exec to non-root.
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
cap_add:
|
|
- SETUID
|
|
- SETGID
|
|
- CHOWN
|
|
- FOWNER
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://localhost:21114/api/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 15s
|
|
|
|
# BetterDesk Console — Node.js Web Interface
|
|
console:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.console
|
|
image: betterdesk-console:local
|
|
pull_policy: never
|
|
container_name: betterdesk-console
|
|
hostname: betterdesk-console
|
|
ports:
|
|
- "5000:5000" # Web console (admin panel)
|
|
- "21121:21121" # Backward compat proxy → Go :21114
|
|
volumes:
|
|
- rustdesk-data:/opt/rustdesk # Shared server data (keys, db) — needs write for WAL mode
|
|
- console-data:/app/data # Console-specific data (auth.db, sessions)
|
|
environment:
|
|
- NODE_ENV=production
|
|
- PORT=5000
|
|
- HOST=0.0.0.0
|
|
- API_HOST=0.0.0.0
|
|
- API_ENABLED=true
|
|
- API_PORT=21121
|
|
- RUSTDESK_API_PROXY=true
|
|
- GO_API_PORT=21114
|
|
- SERVER_BACKEND=betterdesk
|
|
- HBBS_API_URL=http://betterdesk-server:21114/api
|
|
- BETTERDESK_API_URL=http://betterdesk-server:21114/api
|
|
- RUSTDESK_PATH=/opt/rustdesk
|
|
- DATA_DIR=/app/data
|
|
- DB_PATH=/opt/rustdesk/db_v2.sqlite3
|
|
- PUB_KEY_PATH=/opt/rustdesk/id_ed25519.pub
|
|
- API_KEY_PATH=/opt/rustdesk/.api_key
|
|
- SESSION_SECRET=${SESSION_SECRET:-}
|
|
- WS_HBBS_HOST=betterdesk-server
|
|
- WS_HBBS_PORT=21116
|
|
- WS_HBBR_HOST=betterdesk-server
|
|
- WS_HBBR_PORT=21117
|
|
- DOCKER=true
|
|
# Optional: Set custom admin credentials for first run
|
|
# - ADMIN_USERNAME=admin
|
|
# - ADMIN_PASSWORD=YourSecurePassword123
|
|
networks:
|
|
- betterdesk-net
|
|
restart: unless-stopped
|
|
# SECURITY (audit fix L-02, 2026-04-10): drop all caps except those
|
|
# needed by su-exec (SETUID/SETGID) and volume permission fixes (CHOWN/FOWNER).
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
cap_drop:
|
|
- ALL
|
|
cap_add:
|
|
- SETUID
|
|
- SETGID
|
|
- CHOWN
|
|
- FOWNER
|
|
depends_on:
|
|
server:
|
|
condition: service_healthy
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://localhost:5000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 30s
|
|
|
|
# Nginx Reverse Proxy (Optional — only with --profile nginx)
|
|
nginx:
|
|
image: nginx:alpine
|
|
container_name: betterdesk-nginx
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
|
- ./ssl:/etc/nginx/ssl:ro
|
|
networks:
|
|
- betterdesk-net
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- console
|
|
profiles:
|
|
- nginx
|
|
|
|
volumes:
|
|
rustdesk-data:
|
|
driver: local
|
|
driver_opts:
|
|
type: none
|
|
o: bind
|
|
device: ${RUSTDESK_DATA_PATH:-./data}
|
|
|
|
console-data:
|
|
driver: local
|
|
|
|
networks:
|
|
betterdesk-net:
|
|
driver: bridge
|
|
ipam:
|
|
config:
|
|
- subnet: 172.28.0.0/16 |