Document FreeDMR v1.5 Data Gateway setup authored by Simon's avatar Simon
...@@ -2,6 +2,27 @@ ...@@ -2,6 +2,27 @@
Docker is the fastest way to having a running system, complete with proxy and echo, ready to serve repeaters and hotspots. The Docker image can be run on any system that can run Linux docker containers. We recommend Debian 11. Docker is the fastest way to having a running system, complete with proxy and echo, ready to serve repeaters and hotspots. The Docker image can be run on any system that can run Linux docker containers. We recommend Debian 11.
## What HDStack is
HDStack lets one FreeDMR container use several FreeDMR worker processes so it
can use more than one CPU core and serve more than the established
100-connection boundary of one process. The hotspot proxy distributes new HBP
sessions across the workers while keeping each active DMR ID pinned to one
worker. A separate HBP-free aggregator owns the FreeDMR mesh links, and the
container can also run an optional rules-based bridge process, one Loro/ECHO
process per worker and the reporting MUX.
The established recommendation remains to separate repeater access, hotspot
access, defined-TG external bridges such as OBP, HBP and XLXPeer, and FBP v5
FreeDMR mesh links into appropriate FreeDMR instances. The UK FreeDMR servers
continue to use this model. Repeaters and hotspots may also be combined where
that suits the deployment. HDStack packages these
roles and their process separation into one container, simplifying a new
installation or rebuild without forcing the traffic through one Python
process. Ensure the container has adequate CPU and memory; if it is subject to
a CPU limit, set the worker count explicitly to match the resources actually
available to it.
Not convinced? Read [Why Docker?](Why%20Docker) Not convinced? Read [Why Docker?](Why%20Docker)
# Quick Start # Quick Start
...@@ -97,6 +118,163 @@ plus one through the selected worker count. `HDSTACK=1` preserves the ...@@ -97,6 +118,163 @@ plus one through the selected worker count. `HDSTACK=1` preserves the
established single-process layout. An active hotspot DMR ID remains pinned to established single-process layout. An active hotspot DMR ID remains pinned to
one backend port until its proxy session expires; it is not rebalanced live. one backend port until its proxy session expires; it is not rebalanced live.
### Enable HDStack on an existing installation
An existing working Docker installation can enable HDStack without rerunning
the installer:
1. Back up `/etc/freedmr/freedmr.cfg`, the current
`/etc/freedmr/docker-compose.yml`, and any bridge configuration or rules.
2. Compare the local Compose file with the current standard
`docker-compose.yml` rather than overwriting local customisations. Confirm
that the `freedmr` image uses the `latest` tag, add the mounted
`freedmr-bridge.cfg` and `rules-bridge.py` skeleton paths, and retain
`tmpfs: /tmp`. If the skeleton files are absent, install them using the
commands in
[Install the optional bridge skeletons](#install-the-optional-bridge-skeletons).
3. Edit the `freedmr` service's `environment:` list in
`/etc/freedmr/docker-compose.yml`. Set `HDSTACK` to an integer from
`2` through `5`, set `HDSTACK_BASEID` to the main server ID, and leave
`HDSTACK_BRIDGE=0` unless the separate rules-based bridge is required.
4. Ensure the main `freedmr.cfg` has one enabled `[SYSTEM]` section in
`MASTER` mode. This is the common HBP worker template. Its external
FreeDMR mesh links are moved to the generated HBP-free aggregator.
5. If the separate bridge is enabled, give
`/etc/freedmr/freedmr-bridge.cfg` its own server ID, distinct from the
aggregator and worker IDs, then configure `rules-bridge.py`. HDStack
creates the bridge's private FBP v5/FBCP connection to the aggregator.
6. Pull the current image and recreate the service so the changed environment
and mounts take effect:
```sh
cd /etc/freedmr
docker-compose pull freedmr
docker-compose up -d --force-recreate freedmr
docker-compose logs -f freedmr
```
At startup, the log reports the selected worker count and base server ID.
Multi-worker proxy logs then show each numbered backend port range. Existing
hotspot sessions reconnect during the container recreation.
To return to the established single-process layout, set `HDSTACK=1` in
`docker-compose.yml` and recreate the `freedmr` service. Do not remove the
bridge skeleton mounts unless the Compose file is also changed to stop
referencing them.
## Configure the native Data Gateway
FreeDMR v1.5.0 installs the FreeDMR Data Gateway as a separate container for
D-APRS and future packet-data services. The guided installer asks for the
APRS-IS login callsign and passcode, creates a private FBP key, enables the
FreeDMR `[DATA-GATEWAY]` relationship and writes one matching gateway
relationship for each HDStack worker. No manual JSON editing is required when
the guided installer is used.
The standard repository `docker-compose.yml` is an installer template. Do not
start its `data-gateway` service while values such as
`__FREEDMR_GATEWAY_FBP_RELATIONSHIPS__` remain in the file. The gateway will
correctly reject that value because it is not a JSON array.
For an existing installation, back up the configuration and merge the current
`data-gateway` service from the standard Compose file. In `freedmr.cfg`, set:
```ini
[GLOBAL]
DATA_GATEWAY: True
[DATA-GATEWAY]
MODE: OPENBRIDGE
ENABLED: True
PORT: 62041
PASSPHRASE: replace-key
TARGET_IP: freedmr-data-gateway
TARGET_PORT: 62031
RELAX_CHECKS: False
ENHANCED_OBP: True
PROTO_VER: 5
```
Keep the remaining `[DATA-GATEWAY]` fields from the current `FreeDMR.cfg`.
HDStack derives successive worker ports from `PORT` and `TARGET_PORT`.
Set `FREEDMR_GATEWAY_FBP_RELATIONSHIPS` in the gateway container to a JSON
array with one entry per worker. This two-worker example uses aggregator ID
`23400`; worker IDs are therefore `23401` and `23402`. The `key` in every entry
must match the FreeDMR `[DATA-GATEWAY]` passphrase:
```yaml
FREEDMR_GATEWAY_FBP_RELATIONSHIPS: >-
[
{
"link_id": "hdstack-1",
"bind_host": "0.0.0.0",
"bind_port": 62031,
"peer_host": "freedmr",
"peer_port": 62041,
"peer_network_id": 23401,
"direct_source_server_id": 23401,
"key": "replace-key"
},
{
"link_id": "hdstack-2",
"bind_host": "0.0.0.0",
"bind_port": 62032,
"peer_host": "freedmr",
"peer_port": 62042,
"peer_network_id": 23402,
"direct_source_server_id": 23402,
"key": "replace-key"
}
]
```
For `HDSTACK=1`, use one entry with the main server ID and ports `62031` and
`62041`. For multi-worker HDStack, gateway bind ports are `62031` through
`62035`, worker peer ports are `62041` through `62045`, and worker IDs are
`HDSTACK_BASEID + 1` through `HDSTACK_BASEID + HDSTACK`.
Also set:
```yaml
FREEDMR_GATEWAY_RADIOID_PATH: /data/subscriber_ids.json
FREEDMR_GATEWAY_APRS_HOST: rotate.aprs2.net
FREEDMR_GATEWAY_APRS_PORT: '14580'
FREEDMR_GATEWAY_APRS_LOGIN_CALL: 'N0CALL'
FREEDMR_GATEWAY_APRS_PASSCODE: '00000'
FREEDMR_GATEWAY_LOG_LEVEL: INFO
```
Replace the example APRS-IS credentials. Mount FreeDMR's
`/etc/freedmr/json/` directory read-only at `/data/` in the gateway container,
as shown in the standard Compose file. FreeDMR continues to download and
refresh `subscriber_ids.json`.
Use the stable gateway image:
```yaml
image: 'gitlab.hacknix.net:5050/freedmr/freedmr-data-gateway:latest'
```
Then pull and recreate both services:
```sh
cd /etc/freedmr
docker compose pull freedmr data-gateway
docker compose up -d --force-recreate freedmr data-gateway
docker compose logs -f freedmr data-gateway
```
Each worker connects directly to the gateway; the aggregator and optional
bridge process do not. FreeDMR sends locally originated HBP traffic to the
gateway and does not copy peer or mesh ingress back to it. Enabling the native
gateway disables the legacy destination-`900999` D-APRS path, preventing
duplicate APRS-IS reports. There is no automatic fallback if the native link is
unavailable.
See [D-APRS GPS Positioning Support](D-APRS-(GPS-Positioning)-Support) for radio
use and legacy migration notes.
## Add network tuning ## Add network tuning
Add the following to the end of `/etc/sysctl.conf`: Add the following to the end of `/etc/sysctl.conf`:
... ...
......