Tutorial

Remote desktop tutorial

macOS × Ubuntu 24.04: Sunshine + Moonlight implementation guide

Set up Sunshine, Moonlight and Tailscale to control Ubuntu 24.04 from macOS, with verified installation commands, troubleshooting and an Agent Action specification.

Reading time
26 min
Updated
Summary and key figures

Inventory the environment, install pinned versions and validate streaming over the LAN before adding Tailscale for access across networks. Includes the complete Agent Action, troubleshooting and rollback requirements.

Setup steps
7
Initial streaming baseline
1080p / 60 FPS
Verification date
2026-10-16

01Goals and limits

Workflow and scope

This tutorial runs Sunshine on Ubuntu 24.04 Desktop so a Mac can control the existing desktop through official Moonlight. Validate streaming on the same LAN first, then add Tailscale if access across networks is needed.

The baseline assumes a single user who can already log into Ubuntu's graphical desktop, an available display output and someone at the host to approve initial pairing. Sunshine's user service does not create a graphical login session. Headless operation or access after a reboot before login needs a separate design.

Main taskRecommended approach
Animated GUIs, browsers, 3D or the full desktopSunshine + Moonlight; validate the existing GPU and desktop first
Coding Agent commands and file accessUse SSH for execution and recovery, with Moonlight for viewing the GUI
Editing on Mac and running programs on UbuntuSSH + VS Code Remote SSH can be the primary workflow
Remote login immediately after bootEvaluate Ubuntu 24.04 Remote Login separately

02Source article checks

Seven implementation corrections

The source report checked the original article. These corrections affect installation, pairing and validation.

ItemFindingAction
Old DEB filenamesunshine-ubuntu-24.04-amd64.deb does not match this release's namingUse the pinned asset containing the version, Ubuntu version and architecture; verify SHA-256
PIN directionMoonlight displays the PINEnter those digits on Sunshine's PIN page
Built-in VNC on Ubuntu 24.04Ubuntu removed built-in VNC in 22.10The native GNOME remote desktop path needs an RDP client; Mac VNC Screen Sharing cannot connect directly
RDP performance comparisonNo tests use identical hardware, networks and workloads, so there is no basis for claiming Sunshine is universally fasterChoose according to motion or office work; GNOME RDP hardware acceleration improvements in Ubuntu 26.04 do not automatically apply to 24.04
NVIDIA assessmentA successful nvidia-smi only shows communication with the driverUse the existing GPU and check capture, hardware encoding logs and Mac decoding before buying a graphics card
Tailscale pathConnections can use direct, DERP relay or peer-relay pathsCheck the actual path with tailscale ping and tailscale status
Automatic startupEnabling a service does not provide an unattended desktopValidate logged-in use, reconnection and operation after reboot before login separately

032026-10-16

Version and maintenance snapshot

Release dates use the official UTC dates. The verification date uses Asia/Taipei.

ComponentPinned baselineRelease dateSelection and limits
Sunshinev2026.914.2336132026-09-15Official Ubuntu 24.04 amd64 / arm64 DEB, including the Linux security fix
Moonlight PC / Qtv6.2.02026-10-04Official macOS Universal build; adds AV1 hardware decoding on M3 and newer Macs; both ends must support the selected codec
Tailscalev1.104.12026-10-07GitHub stable snapshot; macOS release channels may differ, so record the actual installed version

Do not downgrade a newer installation. Check the official release, Ubuntu 24.04 assets, migration notes and security advisories before updating the version record. New packages require their matching filenames and hashes.

Recent Sunshine changes address Portal capture, Linux encoding and network bind addresses. Moonlight 6.2 changes the default renderer on Mac. Recent commits show maintenance activity, but do not guarantee compatibility with every GPU.

The Moonlight macOS Enhanced release API returned v1.3.9-rc.5, released on 2026-10-13, at verification time. GitHub did not mark it as a prerelease, but its version contains RC and its release notes explicitly describe a prerelease and an architecture rebuild, so it is only a candidate for testing. The latest five commits share an author, which is insufficient to determine how many people maintain the project.

04Streaming pipeline

Capture, encoding and latency

StageLocation and function
Desktop captureUbuntu captures the screen through backends such as Portal or KMS
Video encodingUbuntu encodes through backends such as NVENC, VAAPI or Vulkan
Network transportVideo and audio travel to the Mac; keyboard and mouse input returns to Ubuntu
Decoding and displayThe Mac decodes and displays the stream; applications still run on Ubuntu

capture = portal and encoder = nvenc can be used together because capture and encoding are separate layers. GNOME and KDE have different capture options, so do not copy a kwin setting without checking or treat NvFBC as a general Wayland capture method. Older configuration documentation omitted Portal; see the official documentation correction PR.

Interactive latency includes input, host processing and capture, encoding, networking, decoding and display. A frame at 60 FPS takes about 16.7 ms; this is not the full click-to-display latency. Moonlight's component statistics are not an end-to-end measurement either.

05Choose by task

Alternatives and selection criteria

ToolSuitable tasksLimits to check first
Sunshine + MoonlightA single GPU desktop with continuous motionNeeds a capturable desktop and display output; does not provide file synchronization or independent desktops for multiple users
GNOME Remote Desktop + RDPOffice work and native Remote LoginDistinguish Desktop Sharing from Remote Login and check the actual ports; use an RDP client on Mac
RustDeskRemote support1.5.0 includes Wayland, input and login-screen fixes; test login-screen and package compatibility in the actual environment
OpenSSH + VS Code Remote SSHEditing on Mac and running programs and tools on UbuntuDoes not provide a full desktop

Tailscale is the networking layer and cannot replace a remote desktop tool. Do not rank these tools by performance without measurements under the same conditions.

06Computers, permissions and recovery

Prerequisites

  • Not completed:

    Ubuntu 24.04 Desktop supports normal login, and the single desktop user has the required installation permissions.

  • Not completed:

    The host has an available display output, and someone can approve Portal access during initial setup.

  • Not completed:

    Both computers are initially on the same LAN, and the correct Ubuntu IP is known.

  • Not completed:

    The Mac model, macOS version and CPU architecture are recorded; Homebrew cask 6.2.0 requires macOS 13 or later.

  • Not completed:

    Ubuntu has curl, valid CA certificates and apt; install only missing required tools.

  • Not completed:

    Existing Sunshine settings and service overrides are backed up; pairing keys must not enter public documents or Git.

  • Not completed:

    Local login or an existing SSH recovery path is available, and active work can be saved before a restart.

07Step 1 · Check the host

Ubuntu environment inventory

Connect and turn on a display, then run these commands in the Ubuntu graphical desktop's terminal. An SSH session type does not identify the graphical desktop type. When inventorying over SSH, use loginctl to find the actual graphical session.

bash
cat /etc/os-release
dpkg --print-architecture
uname -r
printf 'Session=%s  Desktop=%s\n' "$XDG_SESSION_TYPE" "$XDG_CURRENT_DESKTOP"
lspci -nnk
hostname -I

For NVIDIA, you can also run nvidia-smi to record the GPU and driver. For Intel / AMD, you can install and run vainfo:

bash
sudo apt install vainfo
vainfo

VAEntrypointEncSlice or VAEntrypointEncSliceLP indicates encoding capability, which still needs confirmation through Sunshine logs and an actual stream. If an NVIDIA driver is missing, check Ubuntu Software & Updates > Additional Drivers first and assess compatibility and restart requirements.

08Step 2 · Sunshine DEB

Pinned version installation

Check the existing version with dpkg-query -W sunshine; the query may report no package if Sunshine is not installed. If a newer stable version is already installed, do not run the older pinned installation block below. Check the installed version against official documentation instead.

This block applies only to Ubuntu 24.04. It selects the official amd64 / arm64 DEB and passes it to apt only after checksum verification succeeds.

bash
(
  set -eu
  . /etc/os-release
  if [ "$ID" != ubuntu ] || [ "$VERSION_ID" != 24.04 ]; then
    echo '此段只適用 Ubuntu 24.04,請改用對應發行版套件。' >&2
    exit 1
  fi
  SUN_ARCH="$(dpkg --print-architecture)"
  case "$SUN_ARCH" in
    amd64) SUN_SHA='c38e9c705f650f8705f61702717e99bec34044c5028fcb8f23a08fe041292c21' ;;
    arm64) SUN_SHA='5751c22cf0b9253b459d7f42103f1c422594363a5881e21bd1ce845218226888' ;;
    *) echo "未涵蓋的架構:$SUN_ARCH" >&2; exit 1 ;;
  esac
  SUN_WORK="$(mktemp -d)"
  cd "$SUN_WORK"
  curl --fail --location --proto '=https' --tlsv1.2 \
    -o sunshine.deb \
    "https://github.com/LizardByte/Sunshine/releases/download/v2026.914.233613/sunshine_2026.914.233613-1%2Bubuntu24.04_${SUN_ARCH}.deb"
  printf '%s  sunshine.deb\n' "$SUN_SHA" | sha256sum --check -
  sudo apt update
  sudo apt install ./sunshine.deb
)

Record the package version after installation:

bash
dpkg-query -W sunshine

Prefer the native package when an official matching DEB is available. Flatpak and AppImage handle capture and permissions differently; do not mix installations. Official prebuilt packages usually do not require a separate CUDA Toolkit installation.

09Step 3 · Sunshine management interface

User service and desktop capture

Run as the Ubuntu desktop user. Do not launch the long-running service from a sudo shell:

bash
systemctl --user start app-dev.lizardbyte.app.Sunshine
systemctl --user status app-dev.lizardbyte.app.Sunshine --no-pager
journalctl --user -u app-dev.lizardbyte.app.Sunshine -b -n 100 --no-pager

Open https://localhost:47990 in Ubuntu's browser and create separate management credentials. The default certificate is self-signed; confirm that the destination is the local Sunshine instance before continuing.

On GNOME Wayland, observe the automatic capture selection first; if needed, select Portal in the Web UI and approve screen sharing or Remote Desktop on the host. Leave encoding on automatic initially and check the actual backend in the logs. An active service confirms only that its process is running.

If the Mac can already connect to Ubuntu through SSH, create this tunnel on the Mac. Replace the account and IP first, keep the terminal connection open, then open the same localhost URL in the Mac browser.

bash
ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:47990:127.0.0.1:47990 ubuntu_user@UBUNTU_IP

The Mac's localhost normally refers to the Mac. The SSH tunnel above forwards that port to Ubuntu. If the host is headless and no one can approve Portal, first choose Remote Login, a virtual display or another headless arrangement.

10Step 4 · Moonlight

Mac installation and pairing

Download the macOS Universal DMG from the official v6.2.0 release and move Moonlight.app into Applications. If Homebrew is already installed, its cask is an option; check the current macOS requirement and version before installation:

bash
brew install --cask moonlight
  1. Manually add Ubuntu's LAN IP in Moonlight.

  2. When Moonlight displays a PIN, enter those digits on the Sunshine Web UI PIN page.

  3. Open Desktop. If it is absent, create a Desktop entry in Sunshine Applications with no launch command to stream the existing desktop.

  4. Check the picture, keyboard, mouse, scrolling, Traditional Chinese input and audio.

Mac Command differs from Ubuntu Ctrl / Super. Record how shortcuts and the host input method behave.

11Step 5 · Change one variable at a time

Streaming performance baseline

SettingInitial value
Resolution1920×1080
Frame rate60 FPS
CodecH.264
Bitrate20 Mbps
ColorSDR
Other optionsKeep defaults

20 Mbps is an engineering test starting point, not the best value for every network. The host display resolution must match or be compatible. Changing Moonlight's resolution does not necessarily change Ubuntu's actual display output.

Use the desktop continuously for 10 minutes and record Moonlight statistics, usually available through Ctrl + Alt / Option + Shift + S. After the baseline passes, change one setting at a time, such as 1440p, HEVC, bitrate, V-sync, renderer or frame rate.

For blurry text, check resolution, scaling, chroma subsampling and codec before increasing bitrate. Do not assume Macs older than M3 support the newly added AV1 hardware decoding. Test the actual workload separately when AI computation also uses the GPU.

12Step 6 · Optional networking layer

Tailscale access across networks

Complete LAN validation before adding Tailscale as needed. On Ubuntu, download and read the official installer first:

bash
curl --fail --location https://tailscale.com/install.sh -o /tmp/tailscale-install.sh
less /tmp/tailscale-install.sh

After review, press q to exit less, then install and log in:

bash
sh /tmp/tailscale-install.sh
sudo tailscale up
tailscale version
tailscale ip -4

On Mac, follow the official macOS installation guide. Join both computers to the same authorized tailnet, with the user completing login, MFA and system network extension approval. Record the actual version at each end.

Manually add Ubuntu's Tailscale IPv4 in Moonlight. Run the following on Ubuntu to check the path to the Mac, replacing the peer name or IP first:

bash
tailscale ping MAC_TAILNET_NAME_OR_IP
tailscale status
PathMeaning
directA direct connection between endpoints
relay / DERPTraffic passes through a Tailscale relay
peer-relayTraffic passes through a peer relay within the tailnet

The initial packets may travel through DERP before the connection becomes direct. If it stays relayed and performance is poor, lower the bitrate first and check the network, host upload capacity and dropped frames.

Disable Sunshine UPnP, do not enable Tailscale Funnel, and do not forward streaming ports or management port 47990 to the public internet. If a connection is blocked, check tailnet grants / ACLs, service listening addresses and the host firewall separately.

13Step 7 · Service lifecycle

Automatic startup and login

Enable automatic startup of the user service only after the preceding tests pass:

bash
systemctl --user enable app-dev.lizardbyte.app.Sunshine

Test reconnection after a disconnect, reconnection after a service restart, then logout and login. Before testing a host reboot, save active work and confirm local login or an SSH recovery path. Do not run a separate manual Sunshine process at the same time.

A user service does not create a graphical desktop before login. loginctl enable-linger does not replace graphical login either. Do not automatically enable autologin, disable the lock screen or modify GRUB to make the test pass.

14Restrict access by source

Moonlight-compatible ports and firewall

FunctionProtocol and portsScope
Streaming controlTCP 47984, 47989, 48010Required client sources
Streaming dataUDP 47998, 47999, 48000, 48002, 48010Required client sources
LAN discoveryUDP 5353LAN; manually entering an IP avoids discovery
Sunshine Web UITCP 47990localhost or an existing SSH tunnel

Check these Moonlight-compatible ports against Sunshine's actual listeners and any custom base port setting; not every UDP port necessarily listens continuously. The Tailscale baseline uses manually entered IPs and does not require mDNS across networks. Do not expose the Web UI directly to the entire network.

Use the following example only when UFW is already enabled and confirmed to be blocking the connection. Review existing rules first, then replace MAC_LAN_IP with the Mac's actual LAN IP:

bash
sudo ufw status numbered
MAC_IP="MAC_LAN_IP"

After replacing the value, add rules that allow only that source:

bash
sudo ufw allow from "$MAC_IP" to any port 47984,47989,48010 proto tcp
sudo ufw allow from "$MAC_IP" to any port 47998,47999,48000,48002,48010 proto udp

Do not reset or disable the existing firewall, or enable UFW on a remote host without checking the consequences. Verify Tailscale netfilter behavior and grants / ACLs separately; do not assume UFW covers all tailnet traffic. Roll back only the rules added in this setup.

15Symptoms, evidence and fixes

Troubleshooting and permission limits

SymptomEvidence to check firstCorrective action
Audio without videoGraphical session, display, Portal and encoder logsRestore capture prerequisites before changing drivers or GRUB
Portal fails after changing the displaySaved token or missing-stream logsConfirm the cause, use Web UI → Troubleshooting → Reset XDG Portal Capture, then approve access again on the host
Video without working inputuinput and the package's udev rulesFollow official documentation to repair or reload rules, or log in again; do not make the device writable by every user
High CPU use or persistent dropped framesWhether a software encoder is actually in useCheck hardware encoding logs for NVENC / VAAPI or the selected backend
LAN works but remote performance is poorTailscale path, upload bandwidth and network frame dropsCompare direct / relay state before adjusting bitrate
Cannot connect after rebootSleep, login, display output and approval stateRecover through existing SSH or locally; design unattended operation separately
Blurry textResolution, scaling, chroma subsampling and codecMatch display settings first; coding work can use a Mac editor + SSH

16Engineering acceptance

Completion checks

These are this tutorial's engineering thresholds, not vendor performance guarantees. Leave untested items unchecked and record pass, fail, blocked or not-tested in the deliverables.

  • Not completed:

    Record Ubuntu / Mac versions, CPU architecture, GPU / driver and graphical session.

  • Not completed:

    LAN pairing succeeds, with picture, keyboard, mouse, Traditional Chinese input and audio checked.

  • Not completed:

    Logs confirm hardware encoding; software-only encoding does not pass the target performance acceptance.

  • Not completed:

    Operate at 1080p60 continuously for 10 minutes without a black screen, a recovery restart or persistent dropped frames.

  • Not completed:

    FPS during motion testing is close to the configured rate; target network frame drops below 1%, or mark unmeasured when there is no counter.

  • Not completed:

    Reconnection, service restart and login each have a separate result.

  • Not completed:

    If access across networks is in scope, record direct / peer-relay / relay and subjective observations from a different network.

  • Not completed:

    No public port forwarding, UPnP or Funnel is enabled; recovery remains available and changes can be rolled back.

17Evidence limited to its environment

Community reports and trial conditions

ReportAvailable informationLimits on conclusions
Moonlight #1929, 2026-07macOS mouse latency discussion, including subjective improvements with Enhanced and maintainer replies on input and display pathsNot a general benchmark; compare on identical hardware, network and resolution when testing
Sunshine #5020, 2026-04 to 2026-08Vulkan artifact reports include Ubuntu 24.04Closure as stale does not establish a fix; retain an NVENC / VAAPI baseline
RustDesk #15417 and 1.5.0DRM / KMS, unattended operation, Wayland and login-screen improvementsActual hardware, package and login state still need testing

The source report did not recommend an official skill dedicated to maintaining this combination. The Agent Action below includes inventory, execution, acceptance and rollback requirements; no additional MCP or third-party skill is needed first.

18Standalone task handoff

Agent Action specification

Use this copyable specification after the user authorizes an Agent to configure the target computers. Reading the tutorial does not execute system commands.

Verification date: 2026-10-16 (Asia/Taipei). This specification can be used independently.

Goal and context

Deploy Sunshine on an Ubuntu 24.04 Desktop host so a Mac can control its existing desktop with Moonlight. First validate 1080p / 60 FPS / SDR streaming on the same LAN, then add Tailscale for access across networks if needed. If the primary workload is a Coding Agent, retain SSH for task execution and recovery, and use Moonlight to view the GUI.

The user has not yet supplied the GPU model, Ubuntu IP, login account, Mac model, macOS version or headless status. Inventory what is available from the authorized target environment first; do not treat the Agent's cloud work container as the user's Ubuntu host. Without a target connection, complete the installation plan and pending scripts, mark the task blocked and ask the user for a target connection method without claiming deployment is complete.

The baseline assumes a single user, an Ubuntu graphical desktop that already supports normal login, an available display output and someone at the host to approve initial pairing. If operation must begin after reboot before login, unattended and without a display, redesign the login and display arrangement first. The standard desktop workflow does not resolve that requirement.

Selected tools and versions

Release dates below use the official UTC dates; the verification date uses Asia/Taipei.

ComponentVerified baselineExecution rule
Ubuntu24.04 DesktopKeep the existing OS; do not upgrade the distribution for streaming
Sunshinev2026.914.233613, released 2026-09-15Official native DEB, selected for amd64 / arm64
Moonlight PC / Qtv6.2.0, released 2026-10-04Official macOS Universal DMG
TailscaleGitHub stable v1.104.1, released 2026-10-07Install when access across networks is needed; record the actual versions on both ends, since platform releases may differ
GPU driverNo assumed versionCheck the actual GPU, Ubuntu package and Sunshine logs; successful nvidia-smi does not pass NVENC validation

Recheck official stable releases and security advisories before execution. If a newer stable release exists, verify its Ubuntu 24.04 assets, migration notes and checksums before use, and update versions.md; do not apply the old checksums below to new files. Do not automatically downgrade a newer existing installation.

Do not use nightly builds, beta releases or forks of unknown origin. This Sunshine baseline fixes GHSA-fp6g-27w5-489j.

Execution order

  1. Inventory and backup

    • Read the management rules that apply to the target project or machine. Confirm where each step runs on Ubuntu or Mac and which permissions it needs.

    • In the Ubuntu graphical user's terminal, collect the OS, architecture, GPU, driver, Wayland/X11, display output, current network and firewall. XDG_SESSION_TYPE in an SSH session does not identify the graphical desktop type; use loginctl to find the actual graphical session.

    • On Mac, collect sw_vers, uname -m and existing Moonlight/Tailscale versions.

    • If Sunshine is installed, identify its source, version, systemd user unit, configuration directory and capture backend. Back up the configuration and required service overrides. Backups contain pairing keys: restrict permissions and keep them out of public reports and Git.

    • List missing prerequisites. Do not install an entire desktop, change the display manager or blindly install NVIDIA drivers on an unidentified GPU.

    • For NVIDIA CUDA / NVFBC capture or direct GPU-memory NVENC, check the pinned CUDA compatibility table: the verified documentation lists CUDA 13.1.1 and minimum driver 590.48.01. If the driver is older, identify a supported path first. A successful nvidia-smi is not proof of compatibility; do not upgrade the driver automatically.

  2. Install Sunshine

    • Use the official DEB by default. Check that the target has curl, CA certificates and apt; install required tools only if missing.

    • The following block installs the report's baseline version reproducibly. Confirm that no newer version is already installed before running it.

bash
(
  set -eu
  . /etc/os-release
  if [ "$ID" != ubuntu ] || [ "$VERSION_ID" != 24.04 ]; then
    echo '此段只適用 Ubuntu 24.04,請改用對應發行版套件。' >&2
    exit 1
  fi
  SUN_ARCH="$(dpkg --print-architecture)"
  case "$SUN_ARCH" in
    amd64) SUN_SHA='c38e9c705f650f8705f61702717e99bec34044c5028fcb8f23a08fe041292c21' ;;
    arm64) SUN_SHA='5751c22cf0b9253b459d7f42103f1c422594363a5881e21bd1ce845218226888' ;;
    *) echo "未涵蓋的架構:$SUN_ARCH" >&2; exit 1 ;;
  esac
  SUN_WORK="$(mktemp -d)"
  cd "$SUN_WORK"
  curl --fail --location --proto '=https' --tlsv1.2 \
    -o sunshine.deb \
    "https://github.com/LizardByte/Sunshine/releases/download/v2026.914.233613/sunshine_2026.914.233613-1%2Bubuntu24.04_${SUN_ARCH}.deb"
  printf '%s  sunshine.deb\n' "$SUN_SHA" | sha256sum --check -
  sudo apt update
  sudo apt install ./sunshine.deb
)
  • Record the version with dpkg-query -W sunshine. Official prebuilt packages usually do not require a separate CUDA Toolkit installation; investigate GPU issues through actual logs.

  1. Graphical session, service and capture

    • Start the user service as the Ubuntu desktop user:

bash
systemctl --user start app-dev.lizardbyte.app.Sunshine
systemctl --user status app-dev.lizardbyte.app.Sunshine --no-pager
journalctl --user -u app-dev.lizardbyte.app.Sunshine -b -n 100 --no-pager
  • On GNOME Wayland, observe automatic selection first. If needed, select XDG Portal capture in the Web UI and approve Remote Desktop / screen sharing on the host. Keep the backend roles distinct: portal handles capture, while nvenc / vaapi / vulkan handle encoding.

  • Let the application choose the initial encoder. If it selects software or encounters compatibility issues, try NVENC or VAAPI according to the GPU. Do not force Vulkan merely because it is newer.

  • Confirm hardware encoding in the actual logs. An active service proves only that the process exists, not that streaming works.

  • Do not run Sunshine as root long term, use chmod 666 /dev/uinput, or copy an old tutorial to add cap_sys_admin manually. The official DEB installation script itself sets cap_sys_admin,cap_sys_nice+p; that differs from adding permissions manually. For input failures, check the package's udev rules first; repair permissions according to official documentation only when evidence shows the need, and record changes.

  1. Mac installation and LAN pairing

    • Download the official v6.2.0 macOS Universal DMG and move Moonlight.app into Applications. If Homebrew is already available, its cask is an option, but check the installed version and current macOS requirements.

    • Open https://localhost:47990 on Ubuntu and create separate management credentials. For management from Mac, use an existing SSH connection to forward to Ubuntu localhost. Mac localhost does not refer to Ubuntu.

    • Manually add Ubuntu's LAN IP in Moonlight. Moonlight displays the PIN; enter it on the Sunshine Web UI PIN page. Do not include management passwords or pairing-state files in the deliverables.

    • Test the Desktop entry. If absent, create a Desktop application with no launch command to stream the existing desktop.

    • Start with 1920×1080, 60 FPS, H.264, 20 Mbps and SDR, leaving other defaults unchanged. These are test starting values, not official optimum settings.

    • Test the mouse, English and Traditional Chinese input, scrolling and audio. Record differences between the host input method and Mac shortcuts.

  2. Networking and Tailscale when access across networks is needed

    • Pass LAN validation first. Install official Tailscale on both ends and join the same authorized tailnet. The user completes login, MFA and system network extension approval.

    • Use the official Linux installation method on Ubuntu and the official macOS package on Mac. Record versions and the Ubuntu Tailscale IPv4.

    • Manually add Ubuntu's Tailscale IP in Moonlight. Use tailscale ping <對端名稱或IP> and tailscale status to confirm whether the eventual path is direct, peer-relay or DERP relay. Initial packets over DERP do not establish that the connection remains relayed.

    • Do not enable Tailscale Funnel or Sunshine UPnP, or forward management or streaming ports to the public internet. Keep the existing firewall running.

    • If a connection is blocked, check tailnet grants/ACL, the OS firewall and service addresses first. Use the current official compatible port table, actual listeners and custom base port setting to add only the minimum rules for required sources. Do not rewrite the entire tailnet policy or assume UFW rules cover all Tailscale netfilter behavior.

    • For Sunshine management from Mac, prefer localhost port forwarding through existing SSH. Do not change origin_web_ui_allowed to wan to expose the management UI.

  3. Tuning, reconnection and restarts

    • Save the 1080p60 baseline, then change only one setting at a time: resolution, bitrate, codec or frame rate. Measure the real workload, particularly when AI computation also occupies the GPU.

    • Use Moonlight statistics to record FPS, network frame drops, decoding time and jitter when displayed. These values do not measure full click-to-display end-to-end latency.

    • Enable systemctl --user enable app-dev.lizardbyte.app.Sunshine only after validation passes. Avoid a second process from a separate manual sunshine launch.

    • Before a restart test, confirm that the user's work is saved and a login or recovery path exists. Test reconnection after a service restart, availability after logging in again and availability after host reboot before login separately. The last case is outside the baseline commitment by default.

    • Neither enable nor loginctl enable-linger creates a graphical desktop. Do not automatically enable autologin, disable the lock screen or modify GRUB.

Acceptance criteria

  • Not completed:

    Record the target OS, CPU architecture, GPU/driver, Mac model and versions at both ends.

  • Not completed:

    LAN pairing works, Desktop displays a picture, mouse and keyboard work, and Chinese input and audio are checked.

  • Not completed:

    Logs confirm hardware encoding. If only software encoding is available, mark target performance acceptance as failed.

  • Not completed:

    Operate at 1080p60 continuously for 10 minutes without a black screen, a recovery restart or persistent dropped frames, and record actual statistics and network conditions. The 10 minutes and following figures are engineering thresholds for this task, not official performance promises: FPS should stay close to the configured rate during smooth motion testing, with a target of network frame drops below 1%. Mark unmeasured if the relevant counter is unavailable.

  • Not completed:

    Reconnection succeeds after a disconnect and after a service restart. Document login-state and display-state limits.

  • Not completed:

    If access across networks is in scope, test from a different network and record direct / peer-relay / relay. A relayed connection can pass functional acceptance, but needs separate performance acceptance.

  • Not completed:

    Public port forwarding and UPnP/Funnel are disabled. Keep existing SSH / recovery access, and make configuration changes reversible.

Required deliverables

  1. environment.md: Actual environment and missing prerequisites; exclude sensitive IPs and accounts from the public version.

  2. versions.md: Versions, official download URLs, SHA-256 and verification date.

  3. setup-log.md: Executed steps, changed files and service state; do not record passwords, keys or authorization tokens.

  4. validation.md: Per-item pass/fail/blocked/not-tested, measured values, test date and session state. Do not mark untested items successful.

  5. rollback.md: Reverse only this setup's changes: stop or disable the service introduced here, restore settings and remove added rules. Do not remove preexisting software or tailnet settings, or downgrade to a version with known vulnerabilities.

Proceed with authorized inventory, installation and reversible fixes. Pause only for actions that would interrupt work, change core login or security arrangements, or require user interaction, and explain the specific reason. This specification authorizes remote desktop setup, not hardware purchases, changes to account privileges or a full OS upgrade.

Official and verification sources

19Official documentation and community records

Sources and verification limits

This page adapts the complete source report, retaining the seven corrections, seven setup steps, troubleshooting and full Agent Action. Verification date: 2026-10-16 (Asia/Taipei). Pinned versions, asset hashes, service names, pairing and ports were also checked against official sources.

Official releases and APIs determine versions; community reports describe only their reported environments. The reader's GPU, network, display and Mac have not been tested. Example thresholds are not measured performance results.

References