Installation
BGPVR runs as a Docker container. The application is stateless — everything that matters lives in the volumes you mount.
On this page
Minimal compose file
services:
bgpvr:
image: ghcr.io/bgpvr/bgpvr:latest
container_name: bgpvr
restart: unless-stopped
network_mode: host
environment:
- BGPVR_DATA=/data
- WEB_PORT=8095
volumes:
- /srv/bgpvr/data:/data
- /srv/bgpvr/recordings:/data/dvr
- /srv/bgpvr/picons:/data/picons
devices:
- /dev/dvb:/dev/dvb # DVB tuners
# - /dev/bus/usb:/dev/bus/usb # USB smartcard readers
# - /dev/dri:/dev/dri # Intel/AMD hardware transcoding
For NVIDIA hardware transcoding add runtime: nvidia and
NVIDIA_DRIVER_CAPABILITIES=compute,utility,video.
Login limits and the other per-address limits count each visitor by the address your reverse proxy
passes in X-Forwarded-For. Tell BGPVR which proxy is yours in the compose
environment: BGPVR_TRUSTED_PROXIES=127.0.0.1/32 for nginx on the same host,
BGPVR_TRUSTED_PROXIES=<its IP>/32 for a proxy elsewhere on your network, or
BGPVR_TRUSTED_PROXIES=none when there is no proxy. An admin can set the same list in the
trusted_proxy_cidrs setting through the settings API; the environment variable wins. The
start-up log line “Client address: …” shows what is in force, and BGPVR logs a hint naming a proxy that
is not listed yet.
Volumes — the container paths are the contract
Host paths are yours to choose, but the container paths must match exactly, and every BGPVR service must see the same ones.
| Container path | Holds |
|---|---|
/data | Database, settings, HLS, logs — the one you cannot lose |
/data/dvr | Recordings (often NAS-backed) |
/data/vod | VOD library and promoted recordings |
/data/picons | Channel logos |
/data/ai_output | Thumbnails, subtitles, AI reports |
/data
Use a bind mount to a real host directory. Named volumes make backup, inspection and migration far harder than they need to be.
Open Monitor → Technical → Storage in the console. Every required path must show as visible. If one says “Needs Mount”, fix the compose mapping before relying on DVR post-processing, thumbnails or VOD scans.
Before you pull a new image and recreate the container, check that no recording is
running (DVR shows what is recording) and that no AI job is processing
(Monitor → Technical → AI Queue, or the Processing count under
Settings → AI Processing → Processing Queue). Queued jobs survive a
restart. A recording cut by a restart resumes as a second file, with a gap. The first
start on 2.9.275 or later moves the guide data into its own database
(epg.db), so allow a few minutes of downtime for that one.
Update BGPVR to the latest version
An update means pulling the new images and recreating the containers. Everything BGPVR keeps (settings, subscribers, channels, recordings) lives in the folders you mounted, so it stays as it is. Do it at a quiet time.
- Make sure nothing is recording. Check DVR and the AI queue, as the warning above describes.
- Take a backup. In the console open Backup and press Backup now (how), then Download the new file to another computer (how). The backup holds the database and the two secrets. Recordings, VOD files and picons are not in it.
- Note your version. The suite version is the small line at the bottom of the sidebar, under Sign Out.
- Pull and restart. On the server, in the folder with your
docker-compose.ymland.envfiles, run:
The first command downloads the latest images of every service in the file, the second recreates the containers that changed. If your file names a version tag instead ofdocker compose pull docker compose up -dlatest, change the tag first. - Wait, then sign in. The server restarts, so live streams stop for a moment, and a recording that is running then resumes as a second file, with a gap. After an update the first start can take a little longer while BGPVR brings its database up to date.
- Confirm. The line at the bottom of the sidebar shows the new version, and License shows your plan as before.
Remote nodes update from the console: a node whose agent is older than the one on this server shows Update agent on the Nodes page (how). Tuner settings and recordings on a node are never touched.
If something fails
- The console opens but shows wrong data or settings: restore the backup from step 2. Open Backup, press Restore on its row and type RESTORE (how). This rewinds the database, not your recordings.
- The console does not open: on the server run
docker compose psanddocker compose logs --tail 100 bgpvr, then contact BGPVR support and send what they print.
Hardware
- Tuners: DVB-C/T/S adapters via
/dev/dvb. Verified example: Hauppauge WinTV-dualHD (Si2168), 2 tuners. - Transcoding: NVIDIA NVENC, or Intel/AMD VAAPI/QSV via
/dev/dri. Optional — CPU works. - Storage speed matters more than size. Slow disks under
/datacause the writers to stall, which shows up as high load and iowait rather than an obvious disk error.
There is no formal minimum spec. As a reference point, a production install caps AI post-processing at 6 of 16 cores so it can never starve live streaming, and each live web viewer needs roughly 40 MB of RAM for its segments (see Settings → Tuners & Sources → Web Player Quality → Segment storage).
The images ghcr.io/bgpvr/bgpvr, bgpvr-ai and
bgpvr-node pull without a login. The operator terms are at
bgpvr.com/terms.
The bgpvr-watchdog container polls the app every minute and alerts through
Settings → Notifications. After 3 missed checks and a 45-second
confirmation it restarts the bgpvr container, at most once every 30 minutes,
but only if /var/run/docker.sock is mounted into the watchdog; without that
mount it only alerts. Opt out with the watchdog_self_heal setting.
NVIDIA persistence mode
Without it, the NVIDIA driver shuts a card down whenever no program is using it and starts it again for the next one: each Light recording stream (and the card check before it) then waits about a second longer. The console shows it per card under Monitor → Technical → Exposed Hardware (Persistence mode: On ✓ or Off) and, when a card is off, the command below. It is a setting of the host's NVIDIA driver: the BGPVR container only reads it.
Check, on the server itself (the host, not inside the container):
nvidia-smi --query-gpu=index,name,persistence_mode --format=csv
The quick way: the script BGPVR ships (Ubuntu, Debian, Proxmox and other hosts with systemd and the NVIDIA driver). It turns persistence mode on now and after every reboot, and prints each card before → after. Take it from the BGPVR image (not from the running container, whose files the app could change) and read it before you run it with sudo:
docker run --rm --entrypoint cat "$(docker inspect -f '{{.Image}}' bgpvr)" \
/app/scripts/host/gpu_persistence.sh > gpu_persistence.sh
less gpu_persistence.sh # read it first
sudo bash gpu_persistence.sh enable # status: show it · disable: undo
The same by hand (Ubuntu / Debian with the NVIDIA driver):
- On now:
sudo nvidia-smi -pm 1 - On after every reboot: create
/etc/systemd/system/nvidia-persistenced.service.d/bgpvr-persistence.confwith
The empty[Service] ExecStart= ExecStart=/usr/bin/nvidia-persistenced --user nvidia-persistenced --persistence-mode --verboseExecStart=clears the distribution's own line (Ubuntu's says--no-persistence-mode). Leave out--user nvidia-persistencedwhengetent passwd nvidia-persistencedprints nothing. - Load it:
sudo systemctl daemon-reload && sudo systemctl enable nvidia-persistenced && sudo systemctl restart nvidia-persistenced - Verify: the check above says
Enabledfor every card, also after a reboot; the console shows On ✓. - Undo:
sudo rm /etc/systemd/system/nvidia-persistenced.service.d/bgpvr-persistence.conf, thensudo systemctl daemon-reload && sudo systemctl restart nvidia-persistenced(the service's own default comes back; Ubuntu's is off)
Other systems
- Unraid has no systemd: run
nvidia-smi -pm 1once and add that line to/boot/config/go, which runs at every boot. - TrueNAS SCALE resets its system files on updates: add
nvidia-smi -pm 1as a Post Init command under System → Advanced → Init/Shutdown Scripts. - Proxmox and virtual machines: do it where the NVIDIA driver runs: inside the VM when the card is passed through to it, on the Proxmox host when containers share the card.
- Synology DSM: untested. Where
nvidia-smiworks over SSH, a boot-time task in Control Panel → Task Scheduler runningnvidia-smi -pm 1as root may do it; otherwise leave it off (the light version still works, about a second slower to start). - Docker Desktop and Windows (WSL): the Windows driver manages the card; nothing to do here.