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
This commit is contained in:
UNITRONIX
2026-04-05 21:13:41 +02:00
parent 66c46f7d93
commit c93a8eb546
3 changed files with 38 additions and 3 deletions
+9 -3
View File
@@ -39,8 +39,9 @@ RUN apk add --no-cache \
curl \
sqlite \
tini \
su-exec \
|| { sleep 2 && apk add --no-cache \
ca-certificates curl sqlite tini; } \
ca-certificates curl sqlite tini su-exec; } \
&& addgroup -g 10001 -S betterdesk \
&& adduser -u 10001 -S -G betterdesk betterdesk
@@ -50,6 +51,10 @@ 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:
@@ -65,7 +70,8 @@ EXPOSE 21114 21115 21116/tcp 21116/udp 21117 21118 21119
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
CMD curl -sf http://localhost:21114/api/health || exit 1
USER betterdesk
# 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", "--"]
ENTRYPOINT ["/sbin/tini", "--", "/server-entrypoint.sh"]
CMD ["/usr/local/bin/betterdesk-server", "-mode", "all", "-key-file", "/opt/rustdesk/id_ed25519"]
+5
View File
@@ -23,6 +23,11 @@ echo ""
# Ensure data directories exist and have correct permissions
mkdir -p /opt/rustdesk /app/data /var/log/betterdesk 2>/dev/null || true
chown -R betterdesk:betterdesk /opt/rustdesk /app/data /var/log/betterdesk 2>/dev/null || true
# Fix private key permissions (volume mounts may preserve wrong UID/mode)
if [ -f /opt/rustdesk/id_ed25519 ]; then
chmod 600 /opt/rustdesk/id_ed25519
chown betterdesk:betterdesk /opt/rustdesk/id_ed25519
fi
# BD-2026-007: Warn about weak default secrets
if [ -n "${SESSION_SECRET}" ] && [ ${#SESSION_SECRET} -lt 32 ]; then
+24
View File
@@ -0,0 +1,24 @@
#!/bin/sh
# BetterDesk Server — Docker Entrypoint
# Fixes volume file permissions before dropping to non-root user
set -e
DATA_DIR="/opt/rustdesk"
# Fix ownership of volume-mounted data directory.
# Docker volumes preserve UID/GID from the host or previous container,
# which may not match the betterdesk user (10001) in this container.
# This is especially important for id_ed25519 (mode 600) — if owned by
# a different UID, the server cannot read the private key.
if [ "$(id -u)" = "0" ]; then
chown -R betterdesk:betterdesk "$DATA_DIR" 2>/dev/null || true
# Ensure private key is readable by betterdesk
if [ -f "$DATA_DIR/id_ed25519" ]; then
chmod 600 "$DATA_DIR/id_ed25519"
chown betterdesk:betterdesk "$DATA_DIR/id_ed25519"
fi
# Drop privileges and re-exec
exec su-exec betterdesk "$@"
else
exec "$@"
fi