Install Nova Core

From a fresh Linux box to live IP streams in a few minutes. One static binary, no dependencies.

System requirements

OSA systemd-based Linux. Tested on Debian 11/12 & Ubuntu 20.04+. Also works on Fedora / RHEL / Rocky / AlmaLinux, openSUSE, Arch, Raspberry Pi OS (64-bit), Armbian.
KernelDVB drivers loaded, with your tuner exposed at /dev/dvb/*.
CPUx86-64-v2 (≈2009+) for the amd64 build, i386 (32-bit x86, SSE2 / Pentium 4+) for the i386 build, or arm64 / armv7.
Privilegesroot — install writes to /opt/nova-core and registers a systemd service.
DependenciesNone. No ffmpeg, no Python, no libc — a single static binary.
Bare-metal recommended. Most DVB cards (e.g. NetUP / cx23885) need real PCIe DMA and do not work reliably under virtualization passthrough. Run on physical hardware for capture.

Non-systemd distros (Alpine, Void, Devuan) can run the binary manually, but the -install command needs systemd.

Download

Grab the build for your CPU architecture — the link always points at the latest release:

amd64nova-core-linux-amd64.tar.gz
arm64nova-core-linux-arm64.tar.gz
armv7nova-core-linux-armv7.tar.gz
i386nova-core-linux-i386.tar.gz

Each tarball ships a .sha256 next to it — verify before extracting:

# example for amd64
sha256sum -c nova-core-linux-amd64.tar.gz.sha256

Install

Quick install (one command)

The fastest path — this detects your CPU, downloads the latest release, unpacks it and runs the installer. Run it as root:

curl -fsSL https://novaheadend.com/install.sh | sudo sh

Manual install

Prefer to do it by hand? Download your build from the table above, then extract and run the installer as root:

tar -xzf nova-core-linux-amd64.tar.gz
sudo ./nova-core -install

Either way, the installer copies the binary to /opt/nova-core, writes a default config, registers a systemd service, starts it, and prints the bootstrap admin password. You'll see something like:

  Nova Core installed
  URL    http://<your-ip>
  user   admin
  pass   3f8c…  (change it in Settings → Users)

The service is now enabled (starts on boot) and listening on two ports: :80 (admin UI) and :8000 (public stream egress).

Docker

Prefer a container? There's an official multi-arch image (amd64 / arm64):

docker run -d --name nova-core \
  --network host \
  --device /dev/dvb \
  -v nova-config:/config \
  -v nova-data:/opt/nova \
  ghcr.io/novaheadend/nova-core:latest

The bootstrap admin password is printed in docker logs nova-core. Pass your tuner devices with --device /dev/dvb/… (or --privileged), and --network host keeps UDP multicast and client access simple. The image rebuilds automatically on every release.

First login

Add a tuner

Budget mode captures the whole transponder TS — required for full EPG and accurate TP-bitrate, at higher CPU. Leave it off unless you need it.

LNB, DiSEqC & Unicable

For DVB-S/S2 tuners, Add/Edit Tuner → Advanced exposes the LNB and dish wiring. The defaults suit a single Universal LNB on its own cable — you only need these for other setups.

LNB type

DiSEqC switch

If several LNBs or satellites feed one tuner through a DiSEqC switch, set DiSEqC switch to the port (1–4 = A–D) for the satellite this tuner should use. Leave it Off for a single LNB.

Force tone

The 22 kHz band-select tone is chosen automatically from the frequency. Force tone (On/Off) overrides it only if your wiring needs a fixed value — normally leave it on Auto.

Unicable / SCR — one cable, many tuners

Unicable (SCR/JESS) lets several tuners share a single coax, each on its own user band. Under Unicable / SCR pick the mode:

Then set the User band index and its User band IF (MHz) — both printed on your LNB or multiswitch. Each tuner on the same cable must use a different user band, or they collide.

Beta: These are implemented to the EN 50494 / EN 50607 / DiSEqC standards. Unicable II (JESS) is confirmed working on real hardware — an 8-tuner TBS6909, 24 h+ locked without issues. Unicable I (SCR), C-band and Ka share the same code path but aren't field-tested yet. If a tuner doesn't lock, please open an issue with your hardware model.

Create a stream

Optional — you don't have to create streams by hand to use Nova. Every service you scan, save and enable is automatically hosted on the playlist (/playlist.m3u). This step is only for advanced users who need custom UDP multicast output, per-stream tuning, or a fixed stream ID.

Access your streams

Every enabled stream is reachable on the stream port (:8000 by default):

HTTP-TShttp://<host>:8000/stream/ts/<id>
Playlisthttp://<host>:8000/playlist.m3u — every enabled stream as M3U
UDPudp://<group>:<port> — when a UDP output is configured

Open any of these in VLC, mpv, or load /playlist.m3u into your IPTV player.

Channel order

The order channels appear in /playlist.m3u — and in the master guide — follows your Streams list. On the Streams page, click the edit-order button next to Playlist to move channels up or down, then Save order. This is the channel numbering your set-top box or IPTV app will show.

EPG (program guide)

Nova harvests the DVB EIT (Event Information Table) straight off a mux and publishes it as XMLTV — the format your IPTV player loads for a program guide. No external grabber, no scraping, no third-party EPG service.

One tuner, the whole bouquet

Most operators broadcast the EPG for every channel on a single mux (a network-wide EIT schedule that includes other-transponder events). Nova tunes that one transponder and collects the guide for hundreds of channels at once — you don't need a tuner per channel. A single budget-mode tuner sitting on the EPG mux gives you the complete lineup's guide.

Add an EPG job

Per-job options

RefreshHow often (seconds) Nova re-harvests and rewrites the file.
Offset (min)Minutes added to every event start time — use it if the broadcaster's EIT clock lags (e.g. +60).
Prune daysDays of past events to keep before trimming.
Future daysDays ahead to include in the guide.

Bind a guide to a channel

The raw harvested XMLTV is keyed by the broadcaster's service ids, which differ from your stream ids and can clash across networks. To get a guide your player lines up with the right channel, bind each stream to one channel of an EPG job:

The master guide

Nova merges every bound stream into a single guide at the reserved name /epg/epg.xml, matched to /playlist.m3u (each bound channel carries a tvg-id). Point your IPTV player at one playlist + one guide and everything lines up:

http://<host>:8000/playlist.m3u     # channels
http://<host>:8000/epg/epg.xml      # merged master guide
http://<host>:8000/epg/guide.xml    # a raw per-mux job (optional)

Works out of the box with TiviMate, Jellyfin, Plex and Xtream-style panels. The raw per-job files stay available for tools that prefer service-id-keyed XMLTV.

Channel logos

Give a channel a logo and it shows up in your player. Edit a stream → Channel logo → paste an image URL. Nova downloads it once, stores it under <DataDir>/logos/, serves it locally, and adds a tvg-logo to /playlist.m3u — so the icon keeps working even if the source link later goes down. The editor previews the remote image as you type and the locally-served copy once you save.

Settings

Everything below lives under Settings in the UI. All values persist to nova.json and survive restarts. Port and runtime changes auto-restart Nova so the new values take effect.

General

Admin UI portPort the admin UI + JSON-RPC listen on (default 80). Changing it auto-restarts Nova so the new listener binds.
Stream portPort the public stream egress (HTTP-TS) listens on (default 8000). Kept separate from the admin port so you can firewall them differently.
GC percent (GOGC)Garbage collector runs when the heap grows this percent since the last collection. 50 keeps RAM tight (more frequent GC, slightly more CPU); 100 is the Go default (less GC, more RAM). Empty = built-in 50.
Memory limit (GOMEMLIMIT)Soft heap ceiling in MB. The runtime runs GC aggressively as the heap approaches it, so RSS stays under it even under load. 2048 (2 GiB) fits ~25 HD streams. Raise for larger installs.

Streaming

Restart schedulerOptionally restart all streams automatically at a chosen day(s) + time — a daily refresh for long-running headends. Off by default.
HTTP-TS bufferPer-client send buffer in KiB. Bitrate-aware: sized to cover a few seconds of a slow client's stall without dropping it. Larger = more tolerance for laggy clients, more RAM per viewer.

Network

Nova handles the modprobe + sysctl writes for these on save and at boot — you never touch the shell.

Kernel TCP bufferCaps per-socket TCP send/receive buffers (MB). Linux auto-tunes each socket up to this ceiling based on RTT × bandwidth. 16 MB covers VPN clients with 100–500 ms RTT. Empty = system defaults.
UDP send bufferPer-socket SO_SNDBUF for UDP/RTP egress (MB). Bigger = more cushion before the kernel drops packets. 4 MB fits ~250 ms of a 128 Mbps mux. Bump for full-mux multicast (50 Mbps+).
TCP congestionCongestion control algorithm. Picking bbr also switches the default qdisc to fq (BBR's pacing needs it). Leave default unless you know you want BBR.

IP whitelist (access control)

The IP Whitelist tab controls who can pull streams. It gates the stream egress port only (:8000) — the admin UI stays behind its own login. Both lists take one entry per line, plain IPs or CIDR blocks, IPv4 or IPv6.

Allow listIf non-empty, only these IPs/ranges may reach /stream/… and /playlist.m3u. Empty = open to everyone.
Deny listThese IPs/ranges are blocked outright, and a deny takes precedence over allow — handy for banning one abusive client while the allow list stays open.

Example — only your LAN and one office IP may pull streams:

# Allow list (one per line)
192.168.1.0/24
203.0.113.5

Update & uninstall

Built-in updater (recommended)

Nova can update itself — no manual download. Open Settings → General → Software updates:

Every apply (manual or automatic) keeps a .bak of the previous build next to the binary, so an update can be rolled back. Your config (nova.json) is never touched.

Unattended boxes: enable Automatically install updates at a quiet hour (e.g. 04:00) and Nova stays current on its own — checksum-verified, with a rollback copy kept.

Manual update

Prefer to do it yourself? Download the new release, stop the service, replace the binary, start again — your config is untouched:

sudo systemctl stop nova-core
sudo cp nova-core /opt/nova-core/nova-core
sudo systemctl start nova-core

Uninstall

sudo ./nova-core -uninstall   # removes service + binary, keeps config JSON

Troubleshooting

permission denied on /dev/dvbThe service must run as root (it does after -install). Running the binary manually as a normal user can't open frontends.
Scan: device or resource busyThe tuner is already locked (by a stream, idle monitor or EPG). Nova snoops a live tuner when re-scanning its own transponder.
Stream shows SCRAMBLEDThe channel is encrypted. Nova Core is free-to-air only and does not descramble encrypted channels.
Logsjournalctl -u nova-core -f, or the Logs page in the UI.