Skip to content

Instantly share code, notes, and snippets.

@yovany-lg
Last active March 16, 2026 21:58
Show Gist options
  • Select an option

  • Save yovany-lg/b26264860ca4778d874e8014833235ef to your computer and use it in GitHub Desktop.

Select an option

Save yovany-lg/b26264860ca4778d874e8014833235ef to your computer and use it in GitHub Desktop.
go2rtc and cloudflare

go2rtc Setup Guide — Windows Mini-PC

Deployment guide for go2rtc on a dedicated Windows mini-PC installed at a condominium, exposed via Cloudflare Tunnel for remote camera viewing.

Prerequisites

  • Windows 10/11 mini-PC (Intel NUC, Beelink, etc.) connected to the condo LAN
  • IP cameras with RTSP streams on the same network
  • Cloudflare account with a domain configured
  • Admin access to the condo router (for static IP assignment)

1. Prepare the Mini-PC

Set a Static IP

Assign a static IP so cameras and services always know where the server is:

  1. Settings > Network & Internet > Ethernet > Edit IP assignment
  2. Set to Manual, e.g. 192.168.1.50, subnet 255.255.255.0, gateway 192.168.1.1

Configure for Unattended Operation

  • Auto-login: Run netplwiz, uncheck "Users must enter a user name and password"
  • Disable sleep: Settings > System > Power > set Sleep to "Never"
  • BIOS: Enable "Power On after AC loss" so it auto-restarts after outages (Beelink: press Delete repeatedly at boot to enter BIOS, then look under Power Management)
  • Windows Update: Schedule reboots for low-traffic hours (e.g. 3 AM)

2. Install go2rtc

Download

  1. Go to https://github.com/AlexxIT/go2rtc/releases/latest
  2. Download go2rtc_win64.zip
  3. Extract go2rtc.exe to C:\go2rtc\

Directory Structure

C:\go2rtc\
├── go2rtc.exe
├── go2rtc.yaml            ← configuration (create this)
├── go2rtc-service.exe     ← WinSW service wrapper (step 4)
├── go2rtc-service.xml     ← WinSW config (step 4)
└── logs\
    └── go2rtc-service.*.log

Create the directories:

mkdir C:\go2rtc
mkdir C:\go2rtc\logs

3. Configure go2rtc

Create C:\go2rtc\go2rtc.yaml:

api:
  listen: ":1984"
  origin: "*"              # Required for Cloudflare Tunnel CORS

rtsp:
  listen: ":8554"

webrtc:
  listen: ":8555"
  candidates:
    - stun:8555

# Camera streams — one entry per camera
# Stream names must match the `streamId` in Sendero's Camera model
streams:
  # Entrance camera (Hikvision example)
  entrance-cam:
    - rtsp://admin:password@192.168.1.100:554/Streaming/Channels/101

  # Exit camera (Dahua example)
  exit-cam:
    - rtsp://admin:password@192.168.1.101:554/cam/realmonitor?channel=1&subtype=0

  # Pool camera (Reolink example)
  # pool-cam:
  #   - rtsp://admin:password@192.168.1.102:554/h264Preview_01_main

log:
  level: info              # Use "debug" when troubleshooting

Finding Your Camera's RTSP URL

Common formats by manufacturer:

Brand Main Stream Sub Stream
Hikvision rtsp://user:pass@IP:554/Streaming/Channels/101 .../Channels/102
Dahua/Amcrest rtsp://user:pass@IP:554/cam/realmonitor?channel=1&subtype=0 subtype=1
Reolink rtsp://user:pass@IP:554/h264Preview_01_main ..._01_sub
Generic ONVIF rtsp://user:pass@IP:554/stream1 /stream2

To discover RTSP URLs:

  • ONVIF Device Manager: Download from https://sourceforge.net/projects/onvifdm/ — discovers cameras on the network and shows their stream URLs
  • Camera web UI: Log into http://<camera-ip> and check network/streaming settings
  • VLC test: Media > Open Network Stream > paste the RTSP URL to verify

Test Manually

cd C:\go2rtc
.\go2rtc.exe

Open http://localhost:1984 in a browser. You should see the go2rtc web UI with your streams listed. Click a stream name to verify video loads.

Press Ctrl+C to stop when done testing.

4. Install as a Windows Service

Use WinSW (Windows Service Wrapper) so go2rtc starts on boot and auto-restarts on crash.

Install WinSW

  1. Download WinSW-x64.exe from https://github.com/winsw/winsw/releases
  2. Rename it to go2rtc-service.exe and place it in C:\go2rtc\

Create the Service Config

Create C:\go2rtc\go2rtc-service.xml:

<service>
  <id>go2rtc</id>
  <name>go2rtc Streaming Server</name>
  <description>RTSP/WebRTC streaming server for condo cameras</description>
  <executable>C:\go2rtc\go2rtc.exe</executable>
  <startmode>Automatic</startmode>
  <log mode="roll-by-size">
    <sizeThreshold>10240</sizeThreshold>
    <keepFiles>3</keepFiles>
  </log>
  <onfailure action="restart" delay="5 sec"/>
  <onfailure action="restart" delay="10 sec"/>
  <onfailure action="restart" delay="30 sec"/>
</service>

Install and Start

Open an Administrator Command Prompt:

C:\go2rtc\go2rtc-service.exe install
C:\go2rtc\go2rtc-service.exe start

Service Management Commands

C:\go2rtc\go2rtc-service.exe start
C:\go2rtc\go2rtc-service.exe stop
C:\go2rtc\go2rtc-service.exe restart
C:\go2rtc\go2rtc-service.exe status
C:\go2rtc\go2rtc-service.exe uninstall

5. Configure Windows Firewall

Open an Administrator PowerShell:

# go2rtc API + Web UI (only localhost — cloudflared connects locally)
New-NetFirewallRule -DisplayName "go2rtc API (localhost)" `
  -Direction Inbound -Protocol TCP -LocalPort 1984 `
  -Action Allow -RemoteAddress 127.0.0.1

# go2rtc RTSP (local network cameras may need this)
New-NetFirewallRule -DisplayName "go2rtc RTSP" `
  -Direction Inbound -Protocol TCP -LocalPort 8554 -Action Allow

# go2rtc WebRTC (for local network direct WebRTC)
New-NetFirewallRule -DisplayName "go2rtc WebRTC TCP" `
  -Direction Inbound -Protocol TCP -LocalPort 8555 -Action Allow
New-NetFirewallRule -DisplayName "go2rtc WebRTC UDP" `
  -Direction Inbound -Protocol UDP -LocalPort 8555 -Action Allow

6. Set Up Cloudflare Tunnel

The tunnel creates a secure outbound connection — no inbound ports need to be opened on the condo router.

Install cloudflared

winget install Cloudflare.cloudflared

Or download cloudflared-windows-amd64.exe from https://github.com/cloudflare/cloudflared/releases and place it in C:\cloudflared\.

Create the Tunnel

# Authenticate (opens browser)
cloudflared tunnel login

# Create a named tunnel
cloudflared tunnel create condo-streams

# Add DNS record
cloudflared tunnel route dns condo-streams streams.your-domain.com

Configure the Tunnel

Create the config file at C:\Users\<username>\.cloudflared\config.yml:

tunnel: <your-tunnel-id>
credentials-file: C:\Users\<username>\.cloudflared\<tunnel-id>.json

ingress:
  - hostname: streams.your-domain.com
    service: http://localhost:1984
    originRequest:
      connectTimeout: 30s
  - service: http_status:404

Test the Tunnel

cloudflared tunnel run condo-streams

Verify https://streams.your-domain.com loads the go2rtc UI from an external network.

Install as a Windows Service

# From Administrator command prompt
cloudflared service install

The service reads config from C:\Windows\System32\config\systemprofile\.cloudflared\. Copy your files there:

mkdir "C:\Windows\System32\config\systemprofile\.cloudflared"

copy "C:\Users\<username>\.cloudflared\config.yml" `
     "C:\Windows\System32\config\systemprofile\.cloudflared\config.yml"

copy "C:\Users\<username>\.cloudflared\<tunnel-id>.json" `
     "C:\Windows\System32\config\systemprofile\.cloudflared\<tunnel-id>.json"

Update the credentials-file path in the copied config to:

credentials-file: C:\Windows\System32\config\systemprofile\.cloudflared\<tunnel-id>.json

Start the service:

net start cloudflared

7. Health Monitoring

Health Check Script

Create C:\go2rtc\healthcheck.ps1:

$ErrorActionPreference = "SilentlyContinue"

try {
    $response = Invoke-WebRequest -Uri "http://localhost:1984/api/streams" `
                -TimeoutSec 5 -UseBasicParsing
    if ($response.StatusCode -ne 200) {
        Write-Output "$(Get-Date) - go2rtc unhealthy (HTTP $($response.StatusCode)), restarting..."
        Restart-Service go2rtc
    }
} catch {
    Write-Output "$(Get-Date) - go2rtc unreachable, restarting..."
    Restart-Service go2rtc
}

Schedule It Every 5 Minutes

Run in an Administrator PowerShell:

$action = New-ScheduledTaskAction `
  -Execute "powershell.exe" `
  -Argument "-ExecutionPolicy Bypass -File C:\go2rtc\healthcheck.ps1"

$trigger = New-ScheduledTaskTrigger `
  -RepetitionInterval (New-TimeSpan -Minutes 5) `
  -Once -At (Get-Date)

$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest

Register-ScheduledTask `
  -TaskName "go2rtc Health Check" `
  -Action $action -Trigger $trigger -Principal $principal `
  -Description "Monitors go2rtc and restarts if unresponsive"

Manual Checks

# Service status
Get-Service go2rtc
Get-Service cloudflared

# Is port 1984 listening?
Test-NetConnection -ComputerName localhost -Port 1984

# View recent logs
Get-Content C:\go2rtc\logs\go2rtc-service.out.log -Tail 50

# Follow logs in real time
Get-Content C:\go2rtc\logs\go2rtc-service.out.log -Wait

# Stream status via API
Invoke-RestMethod http://localhost:1984/api/streams

8. Integration with Sendero Home

How the Web App Connects

The Sendero admin dashboard and mobile app connect through the Cloudflare Tunnel:

Browser/App
    ↓ HTTPS
Cloudflare Edge (streams.your-domain.com)
    ↓ Tunnel
cloudflared (localhost)
    ↓ HTTP/WS
go2rtc (:1984)
    ↓ RTSP
IP Cameras (192.168.1.x)

Stream URLs for the Frontend

Through the tunnel, each camera is accessible at:

Format URL Latency Use Case
MSE (recommended) wss://streams.your-domain.com/api/ws?src=entrance-cam ~1-2s Live view in dashboard
MP4 https://streams.your-domain.com/api/stream.mp4?src=entrance-cam ~2-3s Fallback
MJPEG https://streams.your-domain.com/api/stream.mjpeg?src=entrance-cam ~1s Universal fallback
Snapshot https://streams.your-domain.com/api/frame.jpeg?src=entrance-cam N/A Thumbnails

MSE over WebSocket is the recommended mode — it provides low latency and works through Cloudflare Tunnel since it's pure TCP.

Programmatic Stream Management

When a camera is registered in the Sendero admin panel, the backend syncs it to go2rtc:

# Add a stream
PUT https://streams.your-domain.com/api/streams?name=entrance-cam&src=rtsp://admin:pass@192.168.1.100:554/stream1

# Remove a stream
DELETE https://streams.your-domain.com/api/streams?name=entrance-cam

# List all streams
GET https://streams.your-domain.com/api/streams

MediaServer Record in Sendero DB

When setting up a new condo, create a MediaServer record:

name:      "Las Palmas Streaming Server"
baseUrl:   "http://192.168.1.50:1984"     ← local IP of the mini-PC
tunnelUrl: "https://streams.your-domain.com" ← Cloudflare Tunnel URL

The baseUrl is used for local network access (admin on-site). The tunnelUrl is used for remote access (residents, remote admins).

9. Deployment Checklist

  • Mini-PC has a static IP on the condo LAN
  • Auto-login configured
  • Sleep/hibernate disabled
  • BIOS set to "Power On after AC loss"
  • go2rtc.exe downloaded to C:\go2rtc\
  • go2rtc.yaml configured with camera RTSP URLs
  • All camera streams verified in go2rtc web UI (http://localhost:1984)
  • Firewall rules created for ports 1984, 8554, 8555
  • go2rtc installed as Windows service via WinSW
  • go2rtc service starts on boot (verified after reboot)
  • cloudflared installed and tunnel created
  • DNS record added for tunnel hostname
  • Tunnel config copied to system profile path
  • cloudflared installed as Windows service
  • Streams accessible via https://streams.your-domain.com from external network
  • Health check scheduled task created
  • Full reboot test — both services start, streams accessible remotely
  • MediaServer record created in Sendero admin panel

Troubleshooting

Camera stream shows "loading" but never plays

  • Verify RTSP URL works in VLC: Media > Open Network Stream > paste URL
  • Check camera is on the same subnet as the mini-PC
  • Try adding #transport=tcp to the RTSP URL in go2rtc config:
    entrance-cam:
      - rtsp://admin:pass@192.168.1.100:554/stream1#transport=tcp

go2rtc web UI not accessible remotely

  • Verify cloudflared service is running: Get-Service cloudflared
  • Check tunnel status: cloudflared tunnel info condo-streams
  • Verify DNS record exists: nslookup streams.your-domain.com

Stream works locally but not through tunnel

  • MSE/WebSocket mode is required through Cloudflare Tunnel
  • Direct WebRTC (UDP) will not work — this is expected
  • Ensure the <video-stream> component uses mode="mse,mjpeg" (not mode="webrtc")

High latency (>5 seconds)

  • Use sub-stream URLs (lower resolution) to reduce bandwidth
  • Check the mini-PC's upload speed — each MSE stream uses ~2-4 Mbps for 1080p
  • Reduce camera resolution to 720p if bandwidth is limited
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment