Getting a reliable raspberry pi remote desktop setup vnc anydesk combination right on modern hardware requires navigating the shift from X11 to Wayland. VNC (specifically wayvnc on newer OS versions) gives you high-framerate, low-latency access on your local network, while AnyDesk provides encrypted, NAT-traversing access over the internet without port forwarding. But when you run a headless Pi 5, you lose the physical feedback of knowing if your remote daemons are actually listening.

This guide provides a complete, bench-tested workflow to configure both protocols on a Raspberry Pi 5, bypass the common Wayland display errors, and build a physical GPIO LED status monitor so you know exactly when your remote desktop services are live.

Parts List & Hardware Specifications

This build targets the Raspberry Pi 5 (4GB or 8GB variant) running Raspberry Pi OS (Bookworm or Trixie, 64-bit). The code and pinouts are backward-compatible with the Raspberry Pi 4 Model B, though the Pi 5 requires the 27W USB-C PD power supply to prevent brownouts when driving GPIO and the WiFi radio simultaneously under load.

Bill of Materials (BOM)
Component Specification / Part Number Estimated Cost (2026)
Microcontroller Raspberry Pi 5 (4GB) with Active Cooler $65.00
Power Supply Official 27W USB-C PD Power Supply (5V/5A) $12.00
Storage 64GB MicroSD (SanDisk Extreme Pro) or NVMe via HAT $15.00
Indicators 3x 5mm LEDs (Red, Green, Blue) + 3x 330Ω resistors $2.00
Wiring Female-to-Female jumper wires (Dupont style) $3.00
Headless Dummy HDMI Dummy Plug (1080p/4K EDID emulator) - Optional but recommended $6.00

GPIO Pin Mapping for Status Monitor

When running headless, a physical indicator prevents the guesswork of SSH-ing in just to check if your VNC server crashed. We map three LEDs to the standard 40-pin header to reflect the real-time state of the remote desktop daemons.

Status LED Pin Mapping
Function LED Color BCM GPIO Pin Physical Pin (40-pin Header) Resistor
VNC Active (wayvnc) Green 17 11 330Ω
AnyDesk Active Blue 27 13 330Ω
Service Error / Down Red 22 15 330Ω

Wiring note: Connect the anode (long leg) of each LED to the GPIO pin via the 330Ω resistor, and the cathode (short leg) to any Ground pin (e.g., Physical Pin 9, 14, or 20).

Step-by-Step Raspberry Pi Remote Desktop Setup (VNC & AnyDesk)

Prerequisite: Ensure your Pi is connected to your network and you have SSH access. Run sudo apt update && sudo apt upgrade -y before starting.
  1. Configure the Display Server (Wayland vs X11): Raspberry Pi OS Bookworm and newer default to Wayland. The legacy x11vnc will not work here. We will use wayvnc. If you strictly require legacy X11 VNC, run sudo raspi-config, navigate to Advanced Options > Wayland, and select X11. Reboot. (This guide assumes you are staying on the modern Wayland default).
  2. Install and Enable wayvnc: Install the Wayland-native VNC server.
    sudo apt install wayvnc -y
    Enable it for your user session (do not use sudo for the systemctl user command):
    systemctl --user enable wayvnc
    systemctl --user start wayvnc
  3. Install AnyDesk for WAN Access: AnyDesk handles NAT traversal, meaning you don't need to open port 5900 on your router. Download the official ARM64 Debian package from the AnyDesk Linux repository.
    wget https://download.anydesk.com/linux/anydesk_6.3.2-1_arm64.deb (Verify the latest version number on their site).
    sudo apt install ./anydesk_*.deb -y
  4. Force Headless Resolution: Without a monitor attached, the Pi defaults to a tiny 640x480 framebuffer or fails to start the Wayland compositor. Plug in an HDMI dummy plug to the micro-HDMI port, or edit /boot/firmware/config.txt and add:
    hdmi_force_hotplug=1
    hdmi_group=2
    hdmi_mode=82 (This forces 1080p at 60Hz).
  5. Verify the Services: Check that both are listening.
    ss -tulpn | grep -E '5900|anydesk'

Compilable Code: Remote Service Hardware Monitor

This Python script uses the gpiozero library to poll the process table. If wayvnc is running, the Green LED lights up. If anydesk is running, the Blue LED lights up. If neither is found, the Red LED turns on. This code targets the Raspberry Pi 5 (4GB) and Pi 4 Model B running a 64-bit Debian-based Pi OS.

#!/usr/bin/env python3
"""
Remote Desktop Status Monitor for Raspberry Pi
Targets: Pi 5 / Pi 4 (Bookworm/Trixie 64-bit)
Checks wayvnc and anydesk process states and updates GPIO LEDs.
"""

import subprocess
import time
import sys
import signal

try:
    from gpiozero import LED
except ImportError:
    print("[ERROR] gpiozero not found. Install via: sudo apt install python3-gpiozero")
    sys.exit(1)

# Pin definitions mapped to physical status LEDs (BCM numbering)
VNC_LED = LED(17)     # BCM 17 (Physical Pin 11)
ANYDESK_LED = LED(27) # BCM 27 (Physical Pin 13)
ERROR_LED = LED(22)   # BCM 22 (Physical Pin 15)

POLL_INTERVAL = 5  # Seconds between process checks

def check_process_running(process_name: str) -> bool:
    """Uses pgrep to check if a process is running in user or system space."""
    try:
        # -x ensures exact match, preventing 'wayvnc-config' from triggering 'wayvnc'
        result = subprocess.run(
            ['pgrep', '-x', process_name], 
            stdout=subprocess.DEVNULL, 
            stderr=subprocess.DEVNULL
        )
        return result.returncode == 0
    except Exception as e:
        print(f"[WARN] Failed to check process {process_name}: {e}")
        return False

def cleanup_and_exit(signum, frame):
    """Safely turn off LEDs and exit on SIGINT/SIGTERM."""
    print("\n[INFO] Shutting down status monitor. Turning off LEDs...")
    VNC_LED.off()
    ANYDESK_LED.off()
    ERROR_LED.off()
    sys.exit(0)

# Register signal handlers for clean exits (Ctrl+C or systemd stop)
signal.signal(signal.SIGINT, cleanup_and_exit)
signal.signal(signal.SIGTERM, cleanup_and_exit)

def main():
    print("[INFO] Remote Desktop GPIO Monitor started.")
    print(f"[INFO] Polling every {POLL_INTERVAL} seconds. Press Ctrl+C to exit.")
    
    while True:
        vnc_active = check_process_running('wayvnc')
        anydesk_active = check_process_running('anydesk')
        
        # Update VNC LED
        if vnc_active:
            VNC_LED.on()
        else:
            VNC_LED.off()
            
        # Update AnyDesk LED
        if anydesk_active:
            ANYDESK_LED.on()
        else:
            ANYDESK_LED.off()
            
        # Update Error LED (Red if BOTH are down)
        if not vnc_active and not anydesk_active:
            ERROR_LED.on()
        else:
            ERROR_LED.off()
            
        time.sleep(POLL_INTERVAL)

if __name__ == "__main__":
    main()
How to Extend or Simplify this Build:
Simplify: If you only need local access, drop AnyDesk entirely. Uninstall it, remove the Blue LED from the breadboard, and rely solely on wayvnc to reduce background RAM usage by ~40MB.
Extend: Add the paho-mqtt library to the Python script. When a service drops (Red LED turns on), publish an MQTT payload to your Home Assistant broker to trigger a push notification to your phone.

Debugging: "wayvnc: Failed to connect to Wayland display"

The most common failure point in a modern raspberry pi remote desktop setup vnc anydesk build is the VNC server failing to bind to the display. If you check your logs via journalctl --user -u wayvnc, you will likely see this exact error string:

wayvnc: Failed to connect to Wayland display

First Three Things to Check When It Fails:

  1. Check User Context (The #1 Cause): Wayland sessions are strictly isolated per user. If you started the service using sudo systemctl start wayvnc, it runs as root and cannot see the user's Wayland socket. You must use systemctl --user start wayvnc (no sudo).
  2. Verify XDG_RUNTIME_DIR: The wayvnc binary needs to know where the Wayland socket lives. If running manually from a script, ensure the environment variable is exported: export XDG_RUNTIME_DIR=/run/user/$(id -u).
  3. Check for Headless Compositor Failure: If the Pi booted without an HDMI dummy plug and without hdmi_force_hotplug=1 in config.txt, the Wayfire (or labwc) compositor never started. There is no display to connect to. Plug in the dummy dongle and reboot.

Secondary check: Ensure your firewall (UFW) isn't blocking local traffic if you are testing VNC from another machine on the LAN. Run sudo ufw allow 5900/tcp.

FAQ: Raspberry Pi Remote Desktop Setup VNC AnyDesk

Which is more secure for a raspberry pi remote desktop setup: VNC or AnyDesk?

AnyDesk is inherently more secure for internet-facing (WAN) access because it uses TLS 1.2 encryption and routes traffic through its relay servers, meaning you do not need to open ports on your router's firewall. VNC (wayvnc) natively transmits data with minimal or no encryption depending on the client. For a secure setup, use VNC strictly for local LAN access, and route all external WAN connections through AnyDesk or a WireGuard VPN tunnel.

How do I fix a black screen in my raspberry pi remote desktop setup vnc anydesk?

A black screen with a visible mouse cursor usually means the VNC client connected, but the framebuffer isn't rendering. On Pi 5, this happens if the screen locker (like light-locker or swaylock) has engaged and the VNC session doesn't have the privileges to render the unlocked desktop. Disable the screen blanker in raspi-config under Display Options > Screen Blanking, or pass the --render-cursor flag to your wayvnc configuration file.

Can I use a raspberry pi remote desktop setup vnc anydesk without an internet connection?

Yes, but only the VNC portion. wayvnc operates entirely over your local IP network (e.g., 192.168.1.50:5900) and requires zero internet connectivity. AnyDesk, however, requires an active internet connection to authenticate with its licensing servers and establish the NAT-traversal handshake. If your Pi is on an isolated, air-gapped network, AnyDesk will fail to generate an ID, and you must rely solely on VNC.

Why does AnyDesk show "Waiting for image" on the Pi 5?

This is a hardware acceleration mismatch. AnyDesk attempts to use the Pi's V3D GPU for screen capture. If your OS is missing the mesa-vulkan-drivers or the libraspberrypi0 compatibility layer, it falls back to a software capture method that often hangs on the Pi 5's BCM2712 chip. Fix this by ensuring your system is fully updated (sudo apt full-upgrade) and installing the Vulkan drivers: sudo apt install mesa-vulkan-drivers.