Skip to content

Instantly share code, notes, and snippets.

@adujardin
Last active March 24, 2026 14:47
Show Gist options
  • Select an option

  • Save adujardin/69022c8d5876b4863bd85a865d05290a to your computer and use it in GitHub Desktop.

Select an option

Save adujardin/69022c8d5876b4863bd85a865d05290a to your computer and use it in GitHub Desktop.
Jetson setup xrdp
#!/bin/bash
# Setup xrdp to share the existing GPU-accelerated virtual display (Jetson / headless NVIDIA)
# Prerequisites:
# - Ubuntu 22.04 (Jetson recommended)
# - Will auto-detect and offer to install virtual display if missing
#
# Usage: sudo ./setup-xrdp-virtual-display.sh [username]
#
# Safe to run multiple times (idempotent).
#
# Connect from Remmina (or any RDP client) to <ip>:3389
# At the xrdp login screen, select "ExistingDesktop" and enter any password.
set -e
if [ "$(id -u)" -ne 0 ]; then
echo "Error: must run as root (sudo)."
exit 1
fi
# --- Check if running on a Jetson platform ---
if [ -f /etc/nv_tegra_release ] || [ -d /sys/devices/soc0 ] && grep -qi "tegra\|jetson" /sys/devices/soc0/family 2>/dev/null; then
echo "Jetson platform detected."
else
echo "WARNING: This does not appear to be a Jetson platform."
read -rp "Continue anyway? [y/N] " answer
if [[ ! "$answer" =~ ^[Yy] ]]; then
echo "Aborted."
exit 0
fi
fi
# --- Check if virtual display is configured ---
VIRTUAL_DISPLAY_OK=false
if grep -q 'AllowEmptyInitialConfiguration' /etc/X11/xorg.conf 2>/dev/null && \
grep -q 'CustomEDID' /etc/X11/xorg.conf 2>/dev/null; then
VIRTUAL_DISPLAY_OK=true
echo "Virtual display configuration found in /etc/X11/xorg.conf."
fi
if [ "$VIRTUAL_DISPLAY_OK" = false ]; then
echo "WARNING: Virtual display is not configured."
echo " This script requires a virtual display with nvidia DDX + fake EDID"
echo " to provide a GPU-accelerated headless session (EGL, Argus, CUDA)."
read -rp "Download and run setup-virtual-display.sh? [y/N] " answer
if [[ "$answer" =~ ^[Yy] ]]; then
VDISP_SCRIPT="/tmp/setup-virtual-display.sh"
echo " Downloading setup-virtual-display.sh..."
curl -fsSL "https://gist.githubusercontent.com/adujardin/9154a619cbf5a5508e5fad336839702b/raw/d4d3789928fb4855a6759508171836286f9d991e/setup-virtual-display.sh" -o "$VDISP_SCRIPT"
chmod +x "$VDISP_SCRIPT"
echo " Running setup-virtual-display.sh..."
bash "$VDISP_SCRIPT"
echo " Virtual display setup complete."
else
echo "Aborted. Set up the virtual display first, then re-run this script."
exit 0
fi
fi
USERNAME="${1:-$(logname 2>/dev/null || echo user)}"
USER_UID=$(id -u "$USERNAME")
echo "=== Setting up xrdp for user '$USERNAME' (uid=$USER_UID) ==="
# 1. Enable GDM auto-login (required for headless GNOME session)
echo "[1/5] Configuring GDM auto-login..."
if grep -q "^AutomaticLogin=$USERNAME" /etc/gdm3/custom.conf 2>/dev/null; then
echo " Already configured, skipping."
else
cat > /etc/gdm3/custom.conf << EOF
[daemon]
WaylandEnable=false
AutomaticLoginEnable=true
AutomaticLogin=$USERNAME
[security]
[xdmcp]
[chooser]
[debug]
EOF
echo " Done."
fi
# 2. Install packages
echo "[2/5] Installing xrdp and x11vnc..."
NEEDED=""
dpkg -s xrdp >/dev/null 2>&1 || NEEDED="$NEEDED xrdp"
dpkg -s x11vnc >/dev/null 2>&1 || NEEDED="$NEEDED x11vnc"
if [ -n "$NEEDED" ]; then
apt install -y $NEEDED
else
echo " Already installed, skipping."
fi
# 3. Create x11vnc systemd service
# Auto-detects the display number from /tmp/.X11-unix/
# Runs as the user so it can access the Xauthority
echo "[3/5] Creating x11vnc service..."
cat > /etc/systemd/system/x11vnc.service << SVC
[Unit]
Description=x11vnc VNC server for existing display
After=gdm.service
StartLimitIntervalSec=60
StartLimitBurst=5
[Service]
Type=simple
User=$USERNAME
Environment=XAUTHORITY=/run/user/$USER_UID/gdm/Xauthority
ExecStart=/bin/bash -c 'DISP=\$(ls /tmp/.X11-unix/ | grep X | head -1 | sed s/X/:/); exec /usr/bin/x11vnc -display \$DISP -auth /run/user/$USER_UID/gdm/Xauthority -rfbport 5900 -localhost -forever -nopw -shared -noxdamage'
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
SVC
echo " Done."
# 4. Configure xrdp to connect to the existing display via x11vnc
echo "[4/5] Configuring xrdp..."
if grep -q "^name=ExistingDesktop" /etc/xrdp/xrdp.ini 2>/dev/null; then
echo " Already configured, skipping."
else
# Backup original config (only on first run)
[ ! -f /etc/xrdp/xrdp.ini.orig ] && cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.orig
sed -i '/^\[Xorg\]/,/^code=20/c\[Xorg]\nname=ExistingDesktop\nlib=libvnc.so\nusername=na\npassword=ask\nip=127.0.0.1\nport=5900' /etc/xrdp/xrdp.ini
echo " Done."
fi
# 5. Enable and start services
echo "[5/5] Enabling services..."
systemctl daemon-reload
systemctl enable x11vnc.service
systemctl enable xrdp
echo " Done."
echo ""
echo "=== Setup complete! Reboot for everything to start cleanly. ==="
echo "After reboot, connect via RDP to port 3389."
echo "At the xrdp login screen, select 'ExistingDesktop' and enter any password."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment