mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-11 13:49:03 +00:00
0f161181f1
Privilege separation across all installers so the long-running services no longer run with full administrative rights: betterdesk.sh: installer keeps root but systemd units now run as a dedicated unprivileged 'betterdesk' system account by default (auto-created via ensure_service_user). Added full systemd hardening for the Go server (NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp, ReadWritePaths) and light hardening for the Node.js console. chown migrates existing root-owned data to the service account on update. Opt-out via --run-as-root / BETTERDESK_RUN_AS_ROOT=1; custom account via BETTERDESK_SERVICE_USER. Minimal mode covered too. betterdesk.ps1: NSSM services now run under their per-service low-privilege virtual accounts (NT SERVICE\<service>) instead of LocalSystem, with scoped icacls grants on the install/data dirs (Set-ServiceLeastPrivilege helper). Applied to the Go server, Node.js console and minimal-mode service. Opt-out via -RunAsRoot / BETTERDESK_RUN_AS_ROOT=1. Docker: verified already privilege-separated (supervisord drops both programs to user=betterdesk; multi-container images drop via su-exec). Also bundles in-progress changes to the Go server API, Node.js console services and Docker compose/Dockerfiles. This commit was made possible thanks to Insolve.
85 lines
2.7 KiB
Docker
85 lines
2.7 KiB
Docker
# check=skip=SecretsUsedInArgOrEnv
|
|
# Dockerfile for BetterDesk Console (Node.js)
|
|
# Multi-stage build for smaller production image
|
|
#
|
|
# Stage 1: Install dependencies (cached layer)
|
|
# Stage 2: Production image with only runtime deps
|
|
|
|
# ---- Build stage ----
|
|
FROM node:20-alpine AS build
|
|
|
|
WORKDIR /app
|
|
|
|
# Build dependencies for native modules (better-sqlite3, bcrypt)
|
|
# Note: sqlite-dev is NOT needed — better-sqlite3 bundles its own SQLite
|
|
RUN apk add --no-cache python3 make g++ || { sleep 2 && apk add --no-cache python3 make g++; }
|
|
|
|
# Copy package files first (better Docker cache)
|
|
COPY web-nodejs/package.json web-nodejs/package-lock.json* ./
|
|
|
|
# Install production dependencies (native modules build automatically)
|
|
RUN npm install --production
|
|
|
|
# ---- Production stage ----
|
|
FROM node:20-alpine
|
|
|
|
LABEL maintainer="UNITRONIX"
|
|
LABEL description="BetterDesk Console - Web Management Panel"
|
|
LABEL version="2.4.0"
|
|
|
|
WORKDIR /app
|
|
|
|
# Install runtime dependencies (retry for transient DNS failures)
|
|
RUN apk add --no-cache \
|
|
sqlite \
|
|
curl \
|
|
tini \
|
|
su-exec \
|
|
|| { sleep 2 && apk add --no-cache sqlite curl tini su-exec; } \
|
|
&& addgroup -g 10001 -S betterdesk \
|
|
&& adduser -u 10001 -S -G betterdesk betterdesk
|
|
|
|
# Copy application files FIRST, then overlay compiled node_modules.
|
|
# This prevents local node_modules from overwriting Alpine/musl native modules.
|
|
COPY web-nodejs/ .
|
|
COPY --from=build /app/node_modules ./node_modules/
|
|
|
|
# Copy entrypoint scripts
|
|
COPY docker-entrypoint.sh /app/docker-entrypoint.sh
|
|
COPY docker/console-entrypoint.sh /console-entrypoint.sh
|
|
RUN chmod +x /app/docker-entrypoint.sh /console-entrypoint.sh
|
|
|
|
# Create data directories
|
|
RUN mkdir -p /app/data /opt/rustdesk && \
|
|
chown -R betterdesk:betterdesk /app /opt/rustdesk
|
|
|
|
# Environment variables (defaults)
|
|
ENV NODE_ENV=production
|
|
ENV PORT=5000
|
|
ENV HOST=0.0.0.0
|
|
ENV API_HOST=0.0.0.0
|
|
ENV DATA_DIR=/app/data
|
|
ENV RUSTDESK_PATH=/opt/rustdesk
|
|
ENV DB_PATH=/app/data/db_v2.sqlite3
|
|
ENV PUB_KEY_PATH=/opt/rustdesk/id_ed25519.pub
|
|
ENV API_KEY_PATH=/opt/rustdesk/.api_key
|
|
ENV SERVER_BACKEND=betterdesk
|
|
# API consolidated onto the Go server (21121); the console proxies to it and
|
|
# does not run its own client API listener.
|
|
ENV API_ENABLED=false
|
|
ENV DOCKER=true
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
|
CMD curl -f http://localhost:5000/health || exit 1
|
|
|
|
# Expose ports
|
|
# 5000 - Web console (admin panel)
|
|
EXPOSE 5000
|
|
|
|
# Note: Container starts as root so console-entrypoint.sh can fix volume permissions.
|
|
# It drops to betterdesk user via su-exec before running docker-entrypoint.sh.
|
|
|
|
# Use tini as init to handle signals properly
|
|
ENTRYPOINT ["/sbin/tini", "--"]
|
|
CMD ["/console-entrypoint.sh"] |