Install & getting up and running¶
There are two things you might install:
- The server — the Rafe web app (this is what you browse to).
- Optional SDR add-ons — SatDump (weather/Inmarsat decode) and AIS-catcher (ships), plus remote collectors on Raspberry Pis.
The RS-BA1 server is a separate, self-contained package with its own instructions.
1. Server (Linux Mint / Ubuntu)¶
A single script provisions everything from a fresh Linux Mint 21/22 or Ubuntu 22.04/24.04 machine: system packages, the Python venv, every decoder built from source, the headless-fldigi audio engine, whisper.cpp, Pat/ARDOP and the systemd units.
It is idempotent (safe to re-run) and overridable:
To also stand up the Raspberry Pi collector netboot server (phase 10 —
a safe proxyDHCP + TFTP + NFS server for diskless SDR nodes), add
WITH_PXE=1 (and it enables web management by default; set
ENABLE_WEB_MANAGE=0 to keep it CLI-only):
Then build the Pi roots and register nodes — see docs/pxe-collectors.md.
What it installs (phases 1–9):
- apt: build tools, PulseAudio/ALSA,
multimon-ng, WSJT-X,fldigi+Xvfb, RTL-SDR + SoapySDR (RTL/Lime modules),pat, and the digital-voice build deps. - venv:
aiohttp numpy scipy pillow aprslib sgp4 soundfile pyserial pyaisand SSTV from source. - source builds into
/opt:ft8_lib(FT8/FT4),ardopcf(Winlink),codec2(FreeDV rx+tx),m17-cxx-demod(M17),mbelib+dsd-fme(P25),whisper.cpp+ thebase.enmodel. - services:
icom-remote,fldigi-headless,whisper-server(and Pat).
Build gotchas and their fixes are recorded in
deploy/BUILD-NOTES.md.
Fresh Mint tip: the desktop's Update Manager holds the apt/dpkg lock on first boot — let it finish before (or during; the script waits) the install. On a headless server also disable sleep so it can't suspend:
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
First run¶
# 1. point it at your radio + set a secret
sudoedit /opt/icom-remote/icom-remote.env # ICOM_HOST, TX_ENABLED, SECRET_KEY…
# 2. create a login (give the web login its OWN password — TX radiates!)
cd /opt/icom-remote && USERS_FILE=/opt/icom-remote/users.json \
.venv/bin/python -m app.users add <name>
# 3. start it
sudo systemctl start fldigi-headless whisper-server icom-remote
The app listens on 127.0.0.1:8000. Front it with a reverse proxy for TLS.
Reverse proxy (nginx + self-signed TLS)¶
To reach it over HTTPS on the LAN (e.g. https://<host>/):
sudo apt install -y nginx
sudo openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \
-keyout /etc/ssl/icom-remote/key.pem -out /etc/ssl/icom-remote/cert.pem \
-subj "/CN=<host-ip>" -addext "subjectAltName=IP:<host-ip>"
Configure an nginx vhost that redirects 80→443 and proxies / to
127.0.0.1:8000 with WebSocket upgrade headers (Upgrade/Connection
from a map $http_upgrade), proxy_read_timeout 3600s. The app works behind a
path prefix too (e.g. mounted at /icom in a proxy chain).
icom-remote.env¶
| Key | Meaning |
|---|---|
ICOM_HOST |
the radio (or an rsba1server) IP |
ICOM_USER / ICOM_PASS |
RS-BA1 network login |
TX_ENABLED |
1 to allow transmit at all |
SECRET_KEY |
session signing key (openssl rand -hex 32) |
BIND_HOST / BIND_PORT |
default 127.0.0.1:8000 |
USERS_FILE |
path to users.json |
The env only seeds radios.json on first run; after that the in-app radio
switcher (⚙) is the source of truth.
2. SDR decode add-ons (on the box with the SDR)¶
These are only needed for the SDR features (weather sats, Inmarsat, AIS) and only on the host that has the SDR (e.g. a LimeSDR Mini). They are third-party binaries — install deliberately.
SatDump (weather sats + Inmarsat)¶
# Ubuntu 24.04 example
curl -sL -o /tmp/satdump.deb \
https://github.com/SatDump/SatDump/releases/download/1.2.2/satdump_1.2.2_ubuntu_24.04_amd64.deb
sudo apt install -y /tmp/satdump.deb
Then the DECODE button on Meteor-M/NOAA/Inmarsat birds in the SATS view
drives SatDump against the SDR (native limesdr source; RTL-SDR/Airspy also
supported). Set SATDUMP_SOURCE in the environment to use a different source.
AIS-catcher (ships)¶
sudo apt install -y libsoapysdr-dev librtlsdr-dev cmake build-essential
git clone --depth 1 https://github.com/jvde-github/AIS-catcher /opt/AIS-catcher
cmake -S /opt/AIS-catcher -B /opt/AIS-catcher/build -DCMAKE_BUILD_TYPE=Release
make -C /opt/AIS-catcher/build -j"$(nproc)"
Then AIS in the toolbox → LIME AIS feeds ships from the local SDR.
The local SDR can only do one of these at a time (AIS or a satellite decode) — they stop each other. Remote collectors are independent.
3. Remote collectors (Raspberry Pi + cheap RTL-SDR)¶
To extend coverage, put cheap dongles on Pis around the site and feed the central server. On each Pi: install the RS-BA1 package + AIS-catcher, then:
python3 -m rsba1server --collect ais \
--feed <server-ip>:10110 --serial <dongle-serial> --sdr-gain 40
Run it under systemd so it survives reboots. See the RS-BA1 server guide for the full picture, including serving several SDRs as switchable radios.
Diskless collectors via PXE netboot (recommended for a fleet)¶
Instead of hand-imaging an SD card per Pi, boot them diskless from the
server: one shared root, zero-touch provisioning, central management. The
server runs a safe proxyDHCP (it never assigns IPs — the router keeps
doing DHCP) plus TFTP/NFS; each Pi netboots and runs its assigned collector
(Inmarsat, AIS, or an rtl_tcp relay feeding the native DATV/TETRA
decoders). Online nodes show up in the app's COLLECTOR NODES panel.
sudo bash deploy/pxe/install-pxe-server.sh
sudo COLLECTOR_EXTRAS=satdump,aiscatcher bash deploy/pxe/build-rpi-root.sh
sudo bash deploy/pxe/register-node.sh <pi-serial> inmarsat freq=1541450000
Full guide (Pi EEPROM boot-order setup, roles, safety, troubleshooting): docs/pxe-collectors.md.
Updating¶
Redeploy the tree to /opt/icom-remote (rsync, excluding .venv,
icom-remote.env, users.json, radios.json, freqmem.json, recordings/)
and sudo systemctl restart icom-remote. Static assets are cache-busted with a
?v=N query, so bump it (or hard-refresh) after a UI change.