Phase 4: Updated doc with current progress and native install instructions
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-01-19 00:22:05 +02:00
parent 9b68117144
commit 33a87173e7

View File

@@ -1,15 +1,45 @@
# Phase 4: Remote Gaming (Sunshine + Moonlight)
## Goal
Enable low-latency 60FPS game streaming from Nobara Linux (AMD GPU) to MacBook and Android devices, using Tailscale for optimal network pathing.
## Status: 🔄 IN PROGRESS
**Last Updated:** 2026-01-19
---
## Prerequisites
## Current Progress
- **Gaming PC:** Nobara Linux with AMD GPU (VA-API support)
- **Tailscale:** Installed on gaming PC (from Phase 1)
- **Clients:** MacBook and Android devices with Tailscale
| Task | Status | Notes |
|------|--------|-------|
| Tailscale on Nobara | ✅ Complete | IP: 100.98.57.73 |
| VA-API verification | ✅ Complete | RX 6600 H.264/HEVC encoding working |
| Sunshine Flatpak | ❌ Failed | Capture methods incompatible |
| Native Sunshine | ⏳ Pending | Recommended installation method |
| Moonlight pairing | ⏳ Pending | Awaiting Sunshine setup |
### Verified Hardware
- **GPU:** AMD Radeon RX 6600M (Navi 23) + AMD Radeon 680M (integrated)
- **Driver:** Mesa Gallium 25.3.2 (radeonsi, navi23, LLVM 21.1.7)
- **VA-API:** v1.22 with H.264 and HEVC encode support
### Tailscale Network
| Device | Tailscale IP | Status |
|--------|--------------|--------|
| xtrm-pc (Nobara) | 100.98.57.73 | Online |
| kaloyans-macbook-air | 100.68.118.59 | Online |
| xtrm-unraid | 100.100.208.70 | Online |
### Flatpak Issues Encountered
The Flatpak version of Sunshine failed due to:
1. **wlr capture:** Missing wlr-export-dmabuf protocol (KDE Plasma incompatible)
2. **PipeWire capture:** XDG portal permissions blocked in sandbox
3. **KMS capture:** Cannot apply setcap to sandboxed binaries
**Solution:** Use native DNF installation instead.
---
## Goal
Enable low-latency 60FPS game streaming from Nobara Linux (AMD GPU) to MacBook and Android devices, using Tailscale for optimal network pathing.
---
@@ -26,250 +56,89 @@ Enable low-latency 60FPS game streaming from Nobara Linux (AMD GPU) to MacBook a
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Nobara Gaming PC│ │ MacBook │ │ Android Device │
Sunshine Host │ │ Moonlight Client│ │ Moonlight Client│
│ 100.x.x.x (TS) │ │ 100.x.x.x (TS) │ │ 100.x.x.x (TS)
│ AMD VA-API │ │ │ │ │
xtrm-pc │ │ Moonlight Client│ │ Moonlight Client│
│ 100.98.57.73 │ │ 100.68.118.59 │ │
│ AMD RX 6600 │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
**Why Tailscale for Gaming?**
- Automatic P2P connection when on same LAN
- Encrypted tunnel when remote
- No manual port forwarding required
- MagicDNS for easy hostname resolution
- NAT traversal handled automatically
---
## Installation (Native - Recommended)
### Step 1: Remove Flatpak (if installed)
```bash
flatpak remove dev.lizardbyte.app.Sunshine -y
```
### Step 2: Install Native Sunshine
```bash
sudo dnf copr enable lizardbyte/stable -y
sudo dnf install sunshine -y
```
### Step 3: Set KMS Capture Permission
```bash
sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine))
```
### Step 4: Enable Service
```bash
systemctl --user enable --now sunshine
```
### Step 5: Configure Sunshine
1. Open https://localhost:47990
2. Set admin password
3. Go to Configuration → Video:
- Encoder: vaapi
- Adapter: /dev/dri/renderD128
---
## Implementation Steps
## Moonlight Client Setup
### Step 4.1: Install Sunshine on Nobara
### MacBook
Moonlight already installed. Add PC:
- Host: 100.98.57.73 (Tailscale IP)
- Or hostname: xtrm-pc (if MagicDNS enabled)
**Method A: Flatpak (Recommended for Nobara)**
```bash
# Install via Flatpak
flatpak install flathub dev.lizardbyte.app.Sunshine
# Enable autostart
flatpak run --command=sunshine dev.lizardbyte.app.Sunshine &
```
**Method B: Native Package**
```bash
# Add Sunshine repository
sudo dnf copr enable lizardbyte/stable
sudo dnf install sunshine
# Enable service
sudo systemctl enable --now sunshine
```
**Post-Install:**
1. Access Sunshine web UI: `https://localhost:47990`
2. Set initial admin password
3. Complete setup wizard
### Pairing
1. Open Moonlight, add xtrm-pc
2. Enter 4-digit PIN shown in Moonlight
3. Input PIN in Sunshine Web UI → PIN Pairing
---
### Step 4.2: Configure AMD VA-API Hardware Encoding
## VA-API Verification Output
**Verify AMD GPU:**
```bash
# Check for AMD GPU
lspci | grep -i vga
# Verify VA-API support
vainfo
```
**Expected output:**
```
vainfo: VA-API version: 1.x
vainfo: Driver version: Mesa Gallium driver ...
vainfo: Supported profile and entrypoints:
VAProfileH264Main : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointEncSlice
```
**Configure Sunshine for VA-API:**
1. Open Sunshine Web UI → Configuration → Video
2. Set:
- **Encoder:** `vaapi`
- **Adapter:** `/dev/dri/renderD128` (default AMD)
- **Codec:** `H.265/HEVC` (better compression, lower latency)
**Sunshine config file** (`~/.config/sunshine/sunshine.conf`):
```ini
[video]
encoder = vaapi
adapter_name = /dev/dri/renderD128
hevc_mode = 2 # Always use HEVC when client supports
[stream]
fps = [30, 60, 120]
resolutions = [
1920x1080,
2560x1440,
3840x2160
]
vainfo: VA-API version: 1.22 (libva 2.22.0)
vainfo: Driver version: Mesa Gallium driver 25.3.2 for AMD Radeon RX 6600M
vainfo: Supported profile and entrypoints
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileHEVCMain10 : VAEntrypointEncSlice
```
---
### Step 4.3: Add Applications to Sunshine
**Access:** Sunshine Web UI → Applications
**Recommended Applications:**
| Name | Command | Working Directory |
|------|---------|-------------------|
| Desktop | - | - |
| Steam Big Picture | `steam -bigpicture` | - |
| Lutris | `lutris` | - |
| Heroic Games | `heroic` | - |
**For specific games:**
```
Name: Cyberpunk 2077
Command: steam steam://rungameid/1091500
Detached: ["steam"]
```
---
### Step 4.4: Install Tailscale on Nobara
## Firewall Configuration (Optional)
Restrict Sunshine to Tailscale network only:
```bash
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
# Authenticate
sudo tailscale up
# Get Tailscale IP
tailscale ip -4
```
**Note the Tailscale IP** (e.g., `100.64.x.x`) - clients will connect to this.
---
### Step 4.5: Configure Sunshine for Tailscale
**Sunshine listens on all interfaces by default.** For security, restrict to Tailscale:
**Option A: Bind to Tailscale interface only**
```ini
# ~/.config/sunshine/sunshine.conf
[network]
address_family = both
origin_address = 100.64.x.x # Your Tailscale IP
```
**Option B: Firewall rules (recommended)**
```bash
# Allow Sunshine ports only from Tailscale
sudo firewall-cmd --permanent --zone=trusted --add-source=100.64.0.0/10
sudo firewall-cmd --permanent --zone=trusted --add-port=47984-48010/tcp
sudo firewall-cmd --permanent --zone=trusted --add-port=47998-48010/udp
sudo firewall-cmd --permanent --zone=trusted --add-port=47989/tcp # Web UI
sudo firewall-cmd --permanent --zone=trusted --add-port=47990/tcp # Web UI HTTPS
sudo firewall-cmd --permanent --zone=trusted --add-port=47989-47990/tcp
sudo firewall-cmd --reload
```
---
### Step 4.6: Install Moonlight Clients
#### MacBook
```bash
# Homebrew
brew install --cask moonlight
# Or download from: https://moonlight-stream.org/
```
#### Android
- Install "Moonlight Game Streaming" from Google Play Store
---
### Step 4.7: Pair Moonlight with Sunshine
1. **On Moonlight client:**
- Add PC manually: Enter Tailscale IP (e.g., `100.64.x.x`)
- Or use MagicDNS hostname: `nobara-pc` (if enabled in Tailscale)
2. **Enter PIN:**
- Moonlight displays a 4-digit PIN
- Enter in Sunshine Web UI → PIN Pairing
3. **Verify connection:**
- Moonlight should show your configured applications
---
### Step 4.8: MikroTik QoS for Gaming (Optional but Recommended)
**Goal:** Prioritize Nobara PC traffic to prevent bufferbloat during gaming sessions.
**SSH to MikroTik:**
```bash
ssh -i /root/.ssh/mikrotik_key -p 2222 unraid@192.168.31.1
```
**Create Simple Queue for Gaming PC:**
```routeros
# First, find Nobara's IP (replace with actual)
# Assuming Nobara is at 192.168.31.50
# Create queue for gaming priority
/queue simple add \
name="Gaming-Priority" \
target=192.168.31.50 \
max-limit=0/0 \
priority=1/1 \
queue=default-small/default-small \
comment="Nobara Gaming PC Priority"
# Alternative: Use queue tree for more control
/queue tree add \
name="Gaming-Upload" \
parent=global \
packet-mark=gaming-upload \
priority=1 \
max-limit=50M
/queue tree add \
name="Gaming-Download" \
parent=global \
packet-mark=gaming-download \
priority=1 \
max-limit=100M
# Mark gaming traffic
/ip firewall mangle add \
chain=prerouting \
src-address=192.168.31.50 \
action=mark-packet \
new-packet-mark=gaming-upload \
passthrough=yes
/ip firewall mangle add \
chain=postrouting \
dst-address=192.168.31.50 \
action=mark-packet \
new-packet-mark=gaming-download \
passthrough=yes
```
---
### Step 4.9: Optimize Streaming Settings
**Sunshine Settings (Server):**
## Streaming Settings
| Setting | LAN Value | Remote Value |
|---------|-----------|--------------|
@@ -278,188 +147,44 @@ ssh -i /root/.ssh/mikrotik_key -p 2222 unraid@192.168.31.1
| Resolution | Native | 1080p |
| Codec | HEVC | HEVC |
**Moonlight Settings (Client):**
| Setting | LAN Value | Remote Value |
|---------|-----------|--------------|
| Video Codec | HEVC (if supported) | HEVC |
| Frame Pacing | V-Sync | On |
| Bitrate | Auto or 50+ Mbps | 20 Mbps |
| Resolution | Match display | 1080p |
---
## Network Path Analysis
**Tailscale P2P (Same Network):**
```
MacBook → Router → Nobara PC
Latency: <1ms additional overhead
```
**Tailscale Relayed (Different Network):**
```
MacBook → Tailscale DERP → Nobara PC
Latency: ~20-50ms additional overhead
```
**With Tailscale Direct (NAT Traversal Success):**
```
MacBook (Office) → Internet → Home Router → Nobara PC
Latency: RTT/2 + encoding latency (~30-80ms typical)
```
---
## Service Interruption Assessment
| Action | Risk | Impact | Mitigation |
|--------|------|--------|------------|
| Install Sunshine | NONE | Nobara only | - |
| Install Tailscale | NONE | Nobara only | - |
| MikroTik QoS | LOW | May affect other traffic briefly | Test during low usage |
| Firewall rules | LOW | Nobara only | Can revert |
---
## Verification Checklist
- [ ] Sunshine installed and running on Nobara
- [ ] VA-API encoding verified: `vainfo` shows HEVC support
- [ ] Tailscale running on Nobara: `tailscale status`
- [ ] Sunshine Web UI accessible: `https://<tailscale-ip>:47990`
- [ ] Moonlight paired successfully
- [ ] Desktop streaming works (low latency)
- [ ] Game streaming works at 60 FPS
- [ ] Remote streaming works (via Tailscale from external network)
- [ ] MikroTik QoS queue active (optional)
- [x] Tailscale running on Nobara: 100.98.57.73
- [x] VA-API encoding verified: H.264 + HEVC
- [ ] Sunshine installed (native)
- [ ] KMS capture working
- [ ] Sunshine Web UI accessible
- [ ] Moonlight paired
- [ ] Desktop streaming works
- [ ] Game streaming at 60 FPS
---
## Troubleshooting
### High Latency / Stuttering
### Encoder Fails
```bash
# Verify VA-API
vainfo
1. **Check Tailscale connection type:**
```bash
tailscale status
# Look for "direct" vs "relay"
```
2. **Force direct connection:**
```bash
tailscale ping <client-hostname>
```
3. **Lower bitrate in Moonlight**
### Encoding Errors
1. **Verify VA-API:**
```bash
sudo vainfo
# Should show HEVC/H264 encode support
```
2. **Check Sunshine logs:**
```bash
journalctl -u sunshine -f
# Or: ~/.config/sunshine/sunshine.log
```
3. **Fall back to software encoding:**
```ini
# sunshine.conf
encoder = software
```
### No Audio
1. **Check PulseAudio/PipeWire:**
```bash
pactl list sinks
```
2. **Set Sunshine audio sink:**
- Web UI → Audio → Select correct output
---
## Security Considerations
1. **Tailscale-only access:** Sunshine is only reachable via Tailscale network
2. **PIN pairing:** Each client must be manually paired
3. **Web UI protection:** Consider adding Authentik forward auth (optional)
4. **Firewall:** Block Sunshine ports from non-Tailscale interfaces
---
## Optional: Expose Sunshine Web UI via Traefik
If you want to manage Sunshine remotely via browser:
**Add to Traefik dynamic.yml:**
```yaml
http:
routers:
sunshine-secure:
rule: "Host(`sunshine.xtrm-lab.org`)"
entryPoints:
- https
middlewares:
- default-headers
- authentik-forward-auth # Protect with Authentik
tls:
certResolver: cloudflare
service: sunshine
services:
sunshine:
loadBalancer:
servers:
- url: "https://192.168.31.50:47990" # Nobara IP
# Check Sunshine logs
journalctl --user -u sunshine -f
```
**MikroTik hairpin NAT (if needed):**
```routeros
# Only if accessing from LAN via external hostname
/ip/firewall/nat add chain=srcnat \
action=masquerade \
src-address=192.168.31.0/24 \
dst-address=192.168.31.50 \
dst-port=47990 \
protocol=tcp
### Connection Issues
```bash
# Check Tailscale connectivity
tailscale ping kaloyans-macbook-air
# Verify ports
ss -tlnp | grep sunshine
```
---
## Files Modified
## Related Documents
| File/System | Change | Backup Required |
|-------------|--------|-----------------|
| Nobara: ~/.config/sunshine/ | Sunshine config | No (new install) |
| Nobara: firewalld | Allow Tailscale ports | Can revert |
| MikroTik: Queue | Gaming priority | N/A |
| Traefik dynamic.yml (optional) | Sunshine route | YES |
---
## Performance Expectations
| Scenario | Expected Latency | FPS |
|----------|------------------|-----|
| LAN (same network) | 5-15ms | 60-120 |
| Remote (Tailscale direct) | 30-60ms | 60 |
| Remote (Tailscale relay) | 50-100ms | 60 |
---
## Dependencies for Next Phase
Phase 5 (RustDesk) provides:
- Alternative remote access when gaming not required
- Lower resource usage for general desktop access
- Additional fallback for remote management
- [00-CURRENT-STATE.md](./00-CURRENT-STATE.md) - Infrastructure overview
- [05-PHASE5-RUSTDESK.md](./05-PHASE5-RUSTDESK.md) - RustDesk for general remote access