Hamradio/reflector dashboard
A guide to setting up R.A.D.A.R. (Reflector Activity Dashboard And Reporting): a web dashboard that shows, live, who is connected to your SvxReflector, who is talking, and how the network is wired — with user accounts, talkgroup lists and admin tools.

INSTALL.md; this page is the friendly overview.Do I need this?
- You run a SvxReflector (specifically a GeuReflector build, which adds reflector-to-reflector trunking) and want a public/at-a-glance activity dashboard for it.
- You're comfortable setting up a web server with HTTPS. This is a multi-service install on a Debian box.
- If you only run a node (hotspot/repeater), stop here — use SvxSpot Dashboard.
What you need first
| Thing | Why |
|---|---|
| A running SvxReflector (GeuReflector) on the same box | R.A.D.A.R. reads its /status endpoint (example port 8099).
|
| A domain name + TLS certificate (Let's Encrypt) | Login uses a Secure cookie — it does not work over plain HTTP.
|
| nginx, PHP 8.4 + FPM (redis, mbstring, openssl, json), Redis 6+ | web server, account backend, and account/session store. |
| An MTA or SMTP relay | sign-up verification and password-reset e-mail. |
| Go 1.24+ | to compile the svxdr live-data daemon.
|
Install the packages (Debian 13 / Ubuntu 24.04):
sudo apt install nginx php8.4-fpm php8.4-redis php8.4-mbstring php8.4-cli \
redis-server certbot openssl rsync curl python3 sudo golang-go
8.4.How the data flows (so the ports make sense)
The single most common setup mistake is a mismatched port chain. Data flows:
reflector /status :8099 → svxdr proxy :8090 (caches, enriches) → svxdr nodelist :8098 (builds the API + live SSE stream, reads Redis for node events) → nginx (HTTPS, reverse-proxies /svxportal/api/ to :8098) → your browser. Accounts live in Redis; the PHP backend (auth/*.php) talks to it.
Keep those numbers lined up and most of the install "just works".
Install (overview)
Clone the repo and follow its INSTALL.md steps 0–11; the key moves are:
- Get the code:
git clone https://git.sa7aux.se/bjorne/reflector-dashboard.git - Deploy the web files with
rsyncinto/var/www/html/svxportal(owned bywww-data). - Set up a dedicated Redis instance on a unix socket, with a password; add
www-datato theredisgroup. - Add a second PHP-FPM pool (
svxadmin) used only by the reflector-admin API. - Create the talkgroup-list file
/etc/svxlink/tglist.json(via the shipped tmpfiles rule). - nginx + TLS: install the site template, run
certbotfor your hostname, enable the site. - Build and run
svxdr:
cd svxdr && CGO_ENABLED=0 go build -trimpath -o svxdr . && cd .. sudo install -m0755 svxdr/svxdr /usr/local/bin/svxdr sudo cp install/svxdr.json.example /etc/svxlink/svxdr.json # then edit it sudo cp install/systemd/svxdr.service /etc/systemd/system/svxdr.service sudo systemctl daemon-reload && sudo systemctl enable --now svxdr curl -s http://127.0.0.1:8098/healthz # -> ok
Two config files hold the settings: auth/config.php (web backend — Redis password, mail, base_url, MQTT) and /etc/svxlink/svxdr.json (the daemon — Redis, the three ports, federation seeds). Copy each from its .example and edit.
Create the first admin
A bundled CLI makes the first account (and marks its e-mail verified):
cd /var/www/html/svxportal sudo -u www-data php svx-mkadmin.php
It asks for callsign, name, e-mail, location, admin level and a password. Levels: 1 = normal user, 2 = admin (accounts, nodes, certificates, talkgroups), 3 = super admin (also reflector/MQTT secrets and managing other admins). Everyone else self-registers on the site and verifies by e-mail.
Using it
Open https://YOUR.HOST.NAME/. The top navigation has:
| View | Shows |
|---|---|
| Nodes | Connected nodes, with a pop-up when someone is talking. |
| Reflector clients | Searchable list of all connected clients. |
| Monitor → Nodes / Trunks / Topology | Live monitor; Topology draws the whole network — your reflector in the centre, other reflectors in a ring, trunk links between them. |
| TG Monitor | Who's on each talkgroup (SVX side and DMR side). |
| Lastheard | Recent activity. |
| CTCSS Table | Per-node TX/RX tones, 2 m vs UHF. |
| Changelog | Project changelog. |
A built-in Help page (/help.html) has tabs for the Portal, SvxLink, SvxReflector, GeuReflector, AllStar and more.
Good to know / honest caveats
sudo helpers in /usr/local/sbin/ (svxreflector-pty, svxreflector-systemctl, svxreflector-users, svx-mqtt-provision) that are not shipped — they're specific to your box. Everything else works without them.- Login lost after one page? You're not on HTTPS (the cookie is
Secure) orbase_urlis wrong. - Live views empty?
svxdrisn't running — checksystemctl status svxdrandcurl http://127.0.0.1:8098/healthz. The reflector itself keeps working regardless. - No verification e-mail? PHP
mail()fails silently without an MTA — configure an SMTP relay. - Admin API says “exec disabled”? Never add
execto PHP'sdisable_functions; the portal needs it.
Troubleshooting
| Symptom | Check |
|---|---|
500 on any auth/*.php |
/var/log/nginx/svxportal-error.log and journalctl -u php8.4-fpm — usually Redis password wrong, php-redis missing, or www-data not in group redis.
|
| "Not connected" / empty views | svxdr down → nothing on 127.0.0.1:8098.
|
| Ports | Confirm the chain 8099 → 8090 → 8098 → nginx in /etc/svxlink/svxdr.json and the nginx site.
|
See also
- SvxSpot Dashboard — the dashboard for a single node (much simpler).
- Hamradio — SvxReflector and the rest of the digital-voice how-tos.
- Author: SA7AUX <bjorne@sa7aux.se>. AGPL-3.0-or-later.