Root cause: config.js defaults apiHost to 127.0.0.1 (localhost-only).
Inside Docker containers, this means port 21121 only listens on the
loopback interface, making it unreachable from outside the container
despite docker port mapping.
docker-compose.single.yml already had API_HOST=0.0.0.0, but
docker-compose.yml (multi-container) and docker-compose.quick.yml
(GHCR pre-built) were missing it.
Fixes:
- docker-compose.yml: Add HOST=0.0.0.0 and API_HOST=0.0.0.0
- docker-compose.quick.yml: Add HOST=0.0.0.0 and API_HOST=0.0.0.0
- Dockerfile.console: Add ENV API_HOST=0.0.0.0
- Dockerfile (single): Add ENV API_HOST=0.0.0.0
- docker/entrypoint.sh: Export API_HOST and HOST defaults
- docker/supervisord.conf: Add API_HOST and HOST to console env
Fixes#78
Three related issues reported by user:
1. SQLITE_READONLY: docker-compose.quick.yml mounted /opt/rustdesk as :ro
but console needs read access to .api_key (mode 600). Removed :ro.
2. EACCES .session_secret: Dockerfile.console ran as USER betterdesk
(UID 10001) but volume files owned by different host UID.
3. docker exec fails: container in restart loop due to permission crash.
Fix:
- Add docker/console-entrypoint.sh: starts as root, chown data dirs
to betterdesk user, then drops privileges via su-exec
- Add su-exec to Dockerfile.console runtime packages
- Remove USER betterdesk (entrypoint handles privilege drop)
- Remove :ro from /opt/rustdesk volume mount in docker-compose.quick.yml
Root cause: Dockerfile.server ran as USER betterdesk (UID 10001) but
Docker volume files retain UID/GID from host or previous container.
Private key id_ed25519 (mode 600) owned by different UID = unreadable.
Fix:
- Add docker/server-entrypoint.sh: starts as root, chown+chmod volume
files to betterdesk user, then drops privileges via su-exec
- Add su-exec to Dockerfile.server runtime packages
- Remove USER betterdesk directive (entrypoint handles privilege drop)
- Add explicit chmod 600 + chown for id_ed25519 in all-in-one entrypoint
Implement address book support and related fixes: add address_books table and Get/SaveAddressBook to DB interface with SQLite/Postgres migrations and upsert, add handlers for /api/ab, /api/ab/personal and /api/ab/tags (GET/POST) and normalize/limit incoming data. Signal server: generate relay UUIDs, send RelayResponse (with UUID and signed PK) and forward RequestRelay to targets to ensure hbbr pairing. Docker/compose/supervisord/entrypoint: introduce RELAY_SERVERS env, expose it in Dockerfile and supervisord, add docker-compose hint, and add entrypoint auto-detection/warnings for public IP inside containers. Web UI fixes: align settings password field names and include confirmPassword, modal input supports inputType, fix change-id request body key, add i18n strings for device actions/errors, and improve device delete route error handling. Also update changelog (.github/copilot-instructions.md) and add some API logging and validations.
Fix Docker single-container auth gap by ensuring an API key exists and is discoverable by both the Go server and Node.js console. Changes:
- betterdesk-server/main.go: loadAPIKey() now checks the server_config DB entry and, if absent, auto-generates a 32-byte hex API key, writes it to .api_key (with logging) and continues to sync to the DB.
- docker/entrypoint.sh: generates/persists a 32-byte hex API key at container startup (uses openssl with /dev/urandom fallback) and writes API_KEY env to file if provided.
- web-nodejs/services/betterdeskApi.js: adds fs import and an Axios 401 interceptor that reloads .api_key from disk once and retries the failed request to handle race conditions where the Go server generates the key after Node cached an empty value.
- .github/copilot-instructions.md: documents the Docker API key auto-generation (Phase 16) and related fixes.
- tasks/lessons.md and tasks/todo.md: add lightweight triage notes and actions.
This resolves the issue where the Devices page returned empty results due to missing X-API-Key in the single-container Docker setup and improves resilience during first-run key generation.
Fix port collision between Node.js console (PORT=5000) and Go signal server by introducing SIGNAL_PORT with higher precedence. Changes:
- betterdesk-server/config/config.go: prefer SIGNAL_PORT over PORT when setting SignalPort.
- Dockerfile: add ENV SIGNAL_PORT=21116 default.
- docker/entrypoint.sh: export SIGNAL_PORT with default 21116 before supervisord start.
- docker/supervisord.conf: set SIGNAL_PORT=21116 in Go server environment.
- .github/copilot-instructions.md: document the root cause and fixes; update last-modified date.
This prevents EADDRINUSE races in the single-container Docker setup while keeping multi-container setups unaffected.
Add .dockerignore to trim Docker build context and exclude local artifacts (node_modules, dev files, secrets, runtime DBs, etc.). Simplify Dockerfiles: remove unnecessary sqlite-dev and rely on better-sqlite3's bundled SQLite; use npm install --production in build stages; copy application files first then overlay compiled node_modules from the builder to avoid local node_modules clobbering Alpine-compiled native modules. Update Docker console image similarly. Change supervisord to log to /dev/stdout and /dev/stderr so logs appear in docker logs. Remove explicit compose 'version' keys. Also set SQLite busy_timeout for main and auth DBs to reduce locking errors during concurrent access.
Switch Go builds to CGO_ENABLED=0 and remove system SQLite build deps and static extldflags (modernc.org/sqlite is pure-Go). Remove hardcoded -db flags from server CMD/supervisord and introduce a DB_URL environment variable propagated from entrypoint.sh. entrypoint.sh now sets DB_URL based on DB_TYPE/DATABASE_URL (Postgres or SQLite) and prints the chosen DB, and supervisord is updated to inject DB_URL into the server process. docker-compose files and docs updated to default to SQLite, expose DB_TYPE/DB_URL configuration, and document using a .env or postgres profile for PostgreSQL setups.
Add RustDesk-compatible client API and telemetry support and introduce a single-container Docker build. New client_api_handlers.go implements /api/login, /api/login-options, /api/logout, /api/currentUser, /api/ab, /api/heartbeat, /api/sysinfo and /api/sysinfo_ver with TOTP flow and an in-memory TFA session store; auth middleware and Server registration updated accordingly. Database interface and SQLite/Postgres implementations gain UpdatePeerSysinfo (with tests), audit actions for sysinfo, and handleGetPeer now returns live_online/live_status. Also add Dockerfile, docker-compose.single.yml, supervisord entrypoint, UI fixes (QR color inversion, 403 error view), labels file, README updates, and other ancillary changes.
Co-Authored-By: MrBrodacz - Design <215021251+MrBrodacz2025@users.noreply.github.com>
Co-Authored-By: boruto79 <176351662+boruto79@users.noreply.github.com>
Co-Authored-By: marcosacramento <marcosacramento@gmail.com>
Co-Authored-By: Charles Olivier Savignac <1275666+sircharlo@users.noreply.github.com>