LinuxServer.io containerized MLAT hub aggregating readsb network-only feeds into one combined Beast
4.8K
LinuxServer.io containerized MLAT hub aggregating readsb network-only feeds into one combined Beast output.
Sponsored and maintained by Blackout Secure.
Important
This is not an official LinuxServer.io image release.
When you feed ADS-B data to multiple aggregation services (ADSBExchange, adsb.fi, airplanes.live, etc.), each service runs its own MLAT client that produces multilateration results on separate ports. mlat-hub combines all of these MLAT result feeds into a single, deduplicated Beast output for visualization tools like tar1090 or data collectors.
Warning
MLAT results must **never** be forwarded back to feeders — doing so contaminates MLAT calculations and will get you banned from aggregation services. mlat-hub runs as a separate readsb instance specifically to prevent this cross-contamination.
| Docker Hub | blackoutsecure/mlat-hub |
| GitHub | blackoutsecure/docker-mlat-hub |
| Balena Hub | mlat-hub block |
| Upstream | wiedehopf/readsb |
docker run -d \
--name=mlathub \
--restart unless-stopped \
-e TZ=Etc/UTC \
-e MLATHUB_INPUTS="mlat-adsbx,30105,beast_in;mlat-adsbfi,30105,beast_in" \
-p 30104:30104 \
-p 30105:30105 \
--security-opt no-new-privileges:true \
blackoutsecure/mlat-hub:latest
Combined MLAT results are available on port 30105 (Beast protocol).
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ mlat-client │ │ mlat-client │ │ mlat-client │
│ (ADSBx) │ │ (adsb.fi) │ │ (airplanes │
│ :30105 │ │ :30105 │ │ .live) │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ beast_in │ beast_in │ beast_in
└───────────────────┼───────────────────┘
│
┌──────▼───────┐
│ mlat-hub │
│ (readsb │
│ --net-only │
│ --forward │
│ -mlat) │
└──────┬───────┘
│
Beast output :30105
│
┌────────────┼────────────┐
│ │ │
┌──────▼──────┐ ┌──▼───┐ ┌──────▼──────┐
│ tar1090 │ │ adsb │ │ influxdb/ │
│ (map UI) │ │ -to- │ │ grafana │
└─────────────┘ │ mqtt │ └─────────────┘
└──────┘
--net-connector) and ingests the Beast dataMulti-arch manifest — pulling blackoutsecure/mlat-hub:latest retrieves the correct image for your host.
| Architecture | Tag |
|---|---|
| x86-64 | amd64-latest |
| arm64 | arm64v8-latest |
---
services:
mlathub:
image: blackoutsecure/mlat-hub:latest
container_name: mlathub
environment:
- TZ=Etc/UTC
- MLATHUB_INPUTS=mlat-adsbx,30105,beast_in;mlat-adsbfi,30105,beast_in
ports:
- 30104:30104
- 30105:30105
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp
- /run:exec
restart: unless-stopped
A complete ADS-B receiver stack with readsb, multiple MLAT clients, mlat-hub, and tar1090:
---
services:
readsb:
image: blackoutsecure/readsb:latest
container_name: readsb
environment:
- TZ=Etc/UTC
- READSB_ARGS=--net --device-type rtlsdr
- READSB_AUTOGAIN=true
- FEED_PROFILES=adsbexchange,adsb-fi
- FEED_LAT=51.5074
- FEED_LON=-0.1278
volumes:
- readsb-config:/config
- readsb-run:/run/readsb
devices:
- /dev/bus/usb:/dev/bus/usb
ports:
- 30003:30003
- 30005:30005
restart: unless-stopped
mlat-adsbx:
image: blackoutsecure/mlat-client:latest
container_name: mlat-adsbx
environment:
- MLAT_CLIENT_INPUT_CONNECT=readsb:30005
- MLAT_CLIENT_SERVER=feed.adsbexchange.com:31090
- MLAT_CLIENT_LAT=51.5074
- MLAT_CLIENT_LON=-0.1278
- MLAT_CLIENT_ALT=50m
- MLAT_CLIENT_RESULTS=beast,listen,30105
depends_on: [readsb]
restart: unless-stopped
mlat-adsbfi:
image: blackoutsecure/mlat-client:latest
container_name: mlat-adsbfi
environment:
- MLAT_CLIENT_INPUT_CONNECT=readsb:30005
- MLAT_CLIENT_SERVER=feed.adsb.fi:31090
- MLAT_CLIENT_LAT=51.5074
- MLAT_CLIENT_LON=-0.1278
- MLAT_CLIENT_ALT=50m
- MLAT_CLIENT_RESULTS=beast,listen,30105
depends_on: [readsb]
restart: unless-stopped
mlathub:
image: blackoutsecure/mlat-hub:latest
container_name: mlathub
environment:
- TZ=Etc/UTC
- MLATHUB_INPUTS=mlat-adsbx,30105,beast_in;mlat-adsbfi,30105,beast_in
ports:
- 30105:30105
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp
- /run:exec
depends_on:
- mlat-adsbx
- mlat-adsbfi
restart: unless-stopped
tar1090:
image: mikenye/tar1090:latest
container_name: tar1090
environment:
- TZ=Etc/UTC
- BEASTHOST=readsb
- MLATHOST=mlathub
- LAT=51.5074
- LONG=-0.1278
ports:
- 8078:80
depends_on:
- readsb
- mlathub
restart: unless-stopped
volumes:
readsb-config:
readsb-run:
docker run -d \
--name=mlathub \
-e TZ=Etc/UTC \
-e MLATHUB_INPUTS="mlat-adsbx,30105,beast_in;mlat-adsbfi,30105,beast_in" \
-p 30104:30104 \
-p 30105:30105 \
--security-opt no-new-privileges:true \
--restart unless-stopped \
blackoutsecure/mlat-hub:latest
Deploy to Balena-powered IoT devices using the included docker-compose.yml:
balena push <your-app-slug>
See the Balena Hub listing for details.
| Port | Function |
|---|---|
30104 | Beast input — feeder containers can push MLAT data here |
30105 | Beast output — combined MLAT results |
| Variable | Default | Description |
|---|---|---|
TZ | Etc/UTC | Timezone (TZ database) |
MLATHUB_INPUTS | (empty) | Required. Semicolon-separated host,port,protocol entries. Example: mlat-adsbx,30105,beast_in;mlat-adsbfi,30105,beast_in |
MLATHUB_BEAST_OUTPUT_PORT | 30105 | Beast output port for combined MLAT results |
MLATHUB_BEAST_INPUT_PORT | 30104 | Beast input listen port (push mode) |
MLATHUB_SBS_OUTPUT_PORT | (disabled) | Optional SBS/Basestation output port |
MLATHUB_EXTRA_ARGS | (empty) | Additional readsb arguments |
MLATHUB_USER | abc | Runtime user |
PUID | 911 | User ID for file ownership |
PGID | 911 | Group ID for file ownership |
The protocol field in MLATHUB_INPUTS entries supports:
| Protocol | Description |
|---|---|
beast_in | Beast binary format (most common for MLAT results) |
raw_in | Raw AVR format |
sbs_in | SBS/Basestation format |
There are two ways to get MLAT data into the hub:
Pull mode (recommended): mlat-hub connects to each mlat-client via MLATHUB_INPUTS:
MLATHUB_INPUTS=mlat-adsbx,30105,beast_in;mlat-adsbfi,30105,beast_in
Push mode: MLAT clients connect to the hub's Beast input port:
# mlat-client config
MLAT_CLIENT_RESULTS=beast,connect,mlathub:30104
# mlat-hub config (MLATHUB_INPUTS not required)
MLATHUB_BEAST_INPUT_PORT=30104
Both modes can be used simultaneously.
docker logs mlathubdocker exec mlathub ps aux | grep readsb
docker exec mlathub s6-svstat /run/service/svc-mlathub
| Message | Meaning |
|---|---|
No MLAT inputs configured | No outbound connections — use push mode or set MLATHUB_INPUTS |
N input(s), beast-out=30105 | Hub will connect to N mlat-client containers |
Runs as the LinuxServer.io abc user (non-root) by default. Set PUID and PGID to match a specific host user for file ownership.
Content type
Image
Digest
sha256:414e5a045…
Size
11.9 MB
Last updated
5 months ago
docker pull blackoutsecure/mlat-hub