#!/usr/bin/env bash set -euo pipefail RDP_HOST="${RDP_HOST:?RDP_HOST is required}" RDP_PORT="${RDP_PORT:-3389}" RDP_USER="${RDP_USER:-}" RDP_PASSWORD="${RDP_PASSWORD:-}" RDP_DOMAIN="${RDP_DOMAIN:-}" RDP_SECURITY="${RDP_SECURITY:-}" SESSION_ID="${SESSION_ID:-unknown}" IDLE_TIMEOUT="${IDLE_TIMEOUT:-1800}" ENABLE_HEARTBEAT="${ENABLE_HEARTBEAT:-1}" TOUCH_PATH="${TOUCH_PATH:-/api/sessions/${SESSION_ID}/touch}" SCREEN_GEOMETRY="${SCREEN_GEOMETRY:-1920x1080x24}" DISPLAY_NUM="${DISPLAY_NUM:-:1}" mkdir -p /opt/portal cp -r /usr/share/novnc/* /opt/portal/ cat > /opt/portal/index.html < RDP Session
Ожидайте...
HTML export DISPLAY="$DISPLAY_NUM" DISPLAY_N="${DISPLAY_NUM#:}" rm -f "/tmp/.X${DISPLAY_N}-lock" "/tmp/.X11-unix/X${DISPLAY_N}" 2>/dev/null || true Xvfb "$DISPLAY_NUM" -screen 0 "$SCREEN_GEOMETRY" >/tmp/xvfb.log 2>&1 & sleep 1 RDP_ARGS=( "/v:${RDP_HOST}:${RDP_PORT}" "/cert:ignore" "/f" "/dynamic-resolution" "/gfx-h264:avc444" "/network:auto" "+clipboard" ) if [ -n "$RDP_SECURITY" ]; then RDP_ARGS+=("/sec:${RDP_SECURITY}") fi if [ -n "$RDP_USER" ]; then RDP_ARGS+=("/u:${RDP_USER}") fi if [ -n "$RDP_PASSWORD" ]; then RDP_ARGS+=("/p:${RDP_PASSWORD}") fi if [ -n "$RDP_DOMAIN" ]; then RDP_ARGS+=("/d:${RDP_DOMAIN}") fi xfreerdp "${RDP_ARGS[@]}" >/tmp/xfreerdp.log 2>&1 & XFREERDP_PID=$! x11vnc -display "$DISPLAY_NUM" -rfbport 5900 -forever -shared -nopw -noxdamage >/tmp/x11vnc.log 2>&1 & X11VNC_PID=$! websockify --verbose --idle-timeout="$IDLE_TIMEOUT" --web=/opt/portal 6080 localhost:5900 >/tmp/websockify.log 2>&1 & WEBSOCKIFY_PID=$! # Anti-idle: send Shift key to xfreerdp window every 30s to prevent remote lock screen anti_idle_loop() { sleep 5 while true; do WID=$(DISPLAY="$DISPLAY_NUM" xdotool search --pid "$XFREERDP_PID" 2>/dev/null | head -1) if [ -n "$WID" ]; then DISPLAY="$DISPLAY_NUM" xdotool key --window "$WID" shift 2>/dev/null || true else DISPLAY="$DISPLAY_NUM" xdotool mousemove --sync 500 300 2>/dev/null || true sleep 1 DISPLAY="$DISPLAY_NUM" xdotool mousemove --sync 600 400 2>/dev/null || true fi sleep 30 done } anti_idle_loop & ANTI_IDLE_PID=$! # Graceful shutdown on docker stop (SIGTERM) — exit 0 so Docker does NOT auto-restart cleanup() { kill "$XFREERDP_PID" "$X11VNC_PID" "$WEBSOCKIFY_PID" "$ANTI_IDLE_PID" 2>/dev/null exit 0 } trap cleanup TERM INT # Monitor xfreerdp — when it exits (disconnect/logoff) restart the container wait "$XFREERDP_PID" echo "xfreerdp exited (code $?), triggering container restart" >> /tmp/xfreerdp.log kill "$X11VNC_PID" "$WEBSOCKIFY_PID" 2>/dev/null exit 1