Files
BetterDesk/Dockerfile.server
T
UNITRONIX c93a8eb546 Fix permission denied on id_ed25519 in Docker volumes (#78)
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
2026-04-05 21:13:41 +02:00

78 lines
2.4 KiB
Docker

# Dockerfile for BetterDesk Server (Go)
# Multi-stage build: compile from source, then copy to minimal runtime image
#
# The BetterDesk server is a single binary that replaces both hbbs and hbbr.
# It provides: signal (UDP/TCP/WS), relay (TCP/WS), HTTP API, admin console.
#
# Build: docker build -f Dockerfile.server -t betterdesk-server:local .
# ---- Build stage ----
FROM golang:1.25-alpine AS builder
RUN apk add --no-cache git || { sleep 2 && apk add --no-cache git; }
WORKDIR /src
# Copy Go module files first (cache dependencies)
COPY betterdesk-server/go.mod betterdesk-server/go.sum ./
RUN go mod download
# Copy full source
COPY betterdesk-server/ .
# Build static binary (modernc.org/sqlite is pure Go — no CGO needed)
RUN CGO_ENABLED=0 GOOS=linux go build \
-ldflags="-s -w" \
-tags "netgo osusergo" \
-o /betterdesk-server .
# ---- Runtime stage ----
FROM alpine:3.20
LABEL maintainer="UNITRONIX"
LABEL description="BetterDesk Server - RustDesk-compatible signal + relay"
LABEL version="2.4.0"
RUN apk add --no-cache \
ca-certificates \
curl \
sqlite \
tini \
su-exec \
|| { sleep 2 && apk add --no-cache \
ca-certificates curl sqlite tini su-exec; } \
&& addgroup -g 10001 -S betterdesk \
&& adduser -u 10001 -S -G betterdesk betterdesk
COPY --from=builder /betterdesk-server /usr/local/bin/betterdesk-server
RUN chmod +x /usr/local/bin/betterdesk-server
# Create data directory
RUN mkdir -p /opt/rustdesk && chown betterdesk:betterdesk /opt/rustdesk
# Entrypoint script: fixes volume permissions, then drops to betterdesk user
COPY docker/server-entrypoint.sh /server-entrypoint.sh
RUN chmod +x /server-entrypoint.sh
WORKDIR /opt/rustdesk
# Ports:
# 21114 - HTTP API
# 21115 - NAT type test
# 21116 - Signal (TCP+UDP)
# 21117 - Relay (TCP)
# 21118 - WebSocket Signal
# 21119 - WebSocket Relay
EXPOSE 21114 21115 21116/tcp 21116/udp 21117 21118 21119
# Health check via API
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
CMD curl -sf http://localhost:21114/api/health || exit 1
# Note: Container starts as root so entrypoint can fix volume permissions.
# server-entrypoint.sh drops to betterdesk user via su-exec before running the server.
ENTRYPOINT ["/sbin/tini", "--", "/server-entrypoint.sh"]
CMD ["/usr/local/bin/betterdesk-server", "-mode", "all", "-key-file", "/opt/rustdesk/id_ed25519"]