Deployment guide for go2rtc on a dedicated Windows mini-PC installed at a condominium, exposed via Cloudflare Tunnel for remote camera viewing.
- 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)
Assign a static IP so cameras and services always know where the server is:
- Settings > Network & Internet > Ethernet > Edit IP assignment
- Set to Manual, e.g.
192.168.1.50, subnet255.255.255.0, gateway192.168.1.1
- 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)
- Go to
https://github.com/AlexxIT/go2rtc/releases/latest - Download
go2rtc_win64.zip - Extract
go2rtc.exetoC:\go2rtc\
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\logsCreate 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 troubleshootingCommon 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
cd C:\go2rtc
.\go2rtc.exeOpen 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.
Use WinSW (Windows Service Wrapper) so go2rtc starts on boot and auto-restarts on crash.
- Download
WinSW-x64.exefromhttps://github.com/winsw/winsw/releases - Rename it to
go2rtc-service.exeand place it inC:\go2rtc\
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>Open an Administrator Command Prompt:
C:\go2rtc\go2rtc-service.exe install
C:\go2rtc\go2rtc-service.exe startC:\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 uninstallOpen 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 AllowThe tunnel creates a secure outbound connection — no inbound ports need to be opened on the condo router.
winget install Cloudflare.cloudflaredOr download cloudflared-windows-amd64.exe from https://github.com/cloudflare/cloudflared/releases and place it in C:\cloudflared\.
# 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.comCreate 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:404cloudflared tunnel run condo-streamsVerify https://streams.your-domain.com loads the go2rtc UI from an external network.
# From Administrator command prompt
cloudflared service installThe 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>.jsonStart the service:
net start cloudflaredCreate 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
}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"# 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/streamsThe 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)
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.
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
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).
- 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.exedownloaded toC:\go2rtc\ -
go2rtc.yamlconfigured 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)
-
cloudflaredinstalled and tunnel created - DNS record added for tunnel hostname
- Tunnel config copied to system profile path
-
cloudflaredinstalled as Windows service - Streams accessible via
https://streams.your-domain.comfrom external network - Health check scheduled task created
- Full reboot test — both services start, streams accessible remotely
- MediaServer record created in Sendero admin panel
- 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=tcpto the RTSP URL in go2rtc config:entrance-cam: - rtsp://admin:pass@192.168.1.100:554/stream1#transport=tcp
- 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
- MSE/WebSocket mode is required through Cloudflare Tunnel
- Direct WebRTC (UDP) will not work — this is expected
- Ensure the
<video-stream>component usesmode="mse,mjpeg"(notmode="webrtc")
- 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