mlat-client
LinuxServer.io–style containerized client forwarding Mode S messages for aircraft multilateratio
8.6K
LinuxServer.io–style containerized client forwarding Mode S messages for aircraft multilateration
Unofficial community image for mlat-client, built with LinuxServer.io style container patterns (s6, hardened defaults, practical runtime options) for ADS-B multilateration workloads.
Sponsored and maintained by Blackout Secure.
Important This repository is not an official LinuxServer.io image release.
This project packages upstream wiedehopf/mlat-client into an easy-to-run, LinuxServer.io-style container image with practical defaults for Mode S multilateration clients.
Quick links:
5-minute multilateration client setup:
docker run -d \
--name=mlat-client \
--restart unless-stopped \
-e TZ=Etc/UTC \
-e MLAT_CLIENT_INPUT_CONNECT=readsb:30005 \
-e MLAT_CLIENT_SERVER=feed.adsbexchange.com:31090 \
-e MLAT_CLIENT_LAT=51.5 \
-e MLAT_CLIENT_LON=-0.1 \
-e MLAT_CLIENT_ALT=50m \
-e MLAT_CLIENT_USER_ID=myuser \
-e MLAT_CLIENT_RESULTS=beast,connect,readsb:30104 \
-v mlat-client-config:/config \
blackoutsecure/mlat-client:latest
For compose files, balena, and more examples, see Usage below.
Docker Hub (Recommended):
docker pull blackoutsecure/mlat-client:latest# Pull latest
docker pull blackoutsecure/mlat-client:latest
# Pull specific version
docker pull blackoutsecure/mlat-client:0.4.3
mlat-client is a Mode S multilateration client that selectively forwards Mode S messages to a server that resolves the transmitter position by multilateration of the same message received by multiple clients.
The corresponding server code is available at wiedehopf/mlat-server.
Author and maintenance credits (upstream):
This image is published as a multi-arch manifest. Pulling blackoutsecure/mlat-client:latest retrieves the correct image for your host architecture.
The architectures supported by this image are:
| Architecture | Tag |
|---|---|
| x86-64 | amd64-latest |
| arm64 | arm64v8-latest |
---
services:
mlat-client:
image: blackoutsecure/mlat-client:latest
container_name: mlat-adsbx
environment:
- TZ=Etc/UTC
- MLAT_CLIENT_INPUT_CONNECT=readsb:30005
- MLAT_CLIENT_SERVER=feed.adsbexchange.com:31090
- MLAT_CLIENT_AUTO_LOCATION=true
- MLAT_CLIENT_USER_ID=myuser
- MLAT_CLIENT_RESULTS=beast,connect,readsb:30104
- LOG_LEVEL=info # debug | info | warn | error | fatal
volumes:
- mlat-config:/config
tmpfs:
- /tmp
- /run:exec
restart: unless-stopped
volumes:
mlat-config:
---
services:
readsb:
image: blackoutsecure/readsb:latest
container_name: readsb
environment:
- TZ=Etc/UTC
- READSB_ARGS=--net --device-type rtlsdr --net-bi-port 30004,30104
- READSB_NET_BO_PORT=30005
- READSB_AUTO_LOCATION=true
- READSB_AUTOGAIN=true
# - READSB_BIASTEE=true # enable for powered LNAs (e.g. SAWbird+)
- FEED_PROFILES=adsbexchange
- LOG_LEVEL=info
volumes:
- readsb-config:/config
- readsb-json:/run/readsb
devices:
- /dev/bus/usb:/dev/bus/usb
ports:
- 30001:30001
- 30002:30002
- 30003:30003
- 30004:30004
- 30005:30005
- 30104:30104
privileged: true
tmpfs:
- /tmp
- /run:exec
restart: unless-stopped
mlat-client:
image: blackoutsecure/mlat-client:latest
container_name: mlat-adsbx
depends_on:
- readsb
environment:
- TZ=Etc/UTC
- MLAT_CLIENT_INPUT_CONNECT=readsb:30005
- MLAT_CLIENT_SERVER=feed.adsbexchange.com:31090
- MLAT_CLIENT_AUTO_LOCATION=true
- MLAT_CLIENT_USER_ID=myuser
- MLAT_CLIENT_RESULTS=beast,connect,readsb:30104
- MLAT_CLIENT_UUID_FILE=/readsb-config/feed-uuid-adsbexchange
- LOG_LEVEL=info
volumes:
- mlat-config:/config
- readsb-config:/readsb-config:ro
tmpfs:
- /tmp
- /run:exec
restart: unless-stopped
volumes:
readsb-config:
readsb-json:
mlat-config:
Note: When both services are in the same compose file, Docker Compose creates a shared network automatically — no extra network configuration needed. If you run mlat-client from a separate compose file, create an external network so both containers can communicate:
docker network create adsbThen add to each compose file:
networks: adsb: external: trueAnd add
networks: [adsb]to each service.
docker run -d \
--name=mlat-client \
-e TZ=Etc/UTC \
-e MLAT_CLIENT_INPUT_CONNECT=readsb:30005 \
-e MLAT_CLIENT_SERVER=feed.adsbexchange.com:31090 \
-e MLAT_CLIENT_LAT=51.5 \
-e MLAT_CLIENT_LON=-0.1 \
-e MLAT_CLIENT_ALT=50m \
-e MLAT_CLIENT_USER_ID=myuser \
-e MLAT_CLIENT_RESULTS="beast,connect,readsb:30104" \
-v /path/to/mlat-client/config:/config \
--restart unless-stopped \
blackoutsecure/mlat-client:latest
This image can be deployed to Balena-powered IoT devices using the included docker-compose.yml file (which contains the required Balena labels):
balena push <your-app-slug>
For deployment via the web interface, use the deploy button in this repository. See Balena documentation for details.
| Parameter | Description | Example |
|---|---|---|
-e MLAT_CLIENT_LAT= | Receiver latitude in decimal degrees (auto-detected if empty and MLAT_CLIENT_AUTO_LOCATION=true) | 51.5 |
-e MLAT_CLIENT_LON= | Receiver longitude in decimal degrees (auto-detected if empty and MLAT_CLIENT_AUTO_LOCATION=true) | -0.1 |
-e MLAT_CLIENT_ALT= | Receiver altitude with unit (m or ft); auto-detected from terrain elevation when MLAT_CLIENT_AUTO_ALT=true and alt is not set | 50m |
-e MLAT_CLIENT_USER_ID= | User identifier for the MLAT server | myuser |
| Parameter | Default | Description |
|---|---|---|
-e TZ=Etc/UTC | Etc/UTC | Timezone (TZ database) |
-e MLAT_CLIENT_INPUT_CONNECT= | readsb:30005 | Beast data source (host:port) |
-e MLAT_CLIENT_SERVER= | feed.adsbexchange.com:31090 | Multilateration server (host:port) |
-e MLAT_CLIENT_RESULTS= | (none) | Results output destination(s) |
-e MLAT_CLIENT_UUID= | (none) | UUID sent to the server |
-e MLAT_CLIENT_UUID_FILE= | /config/feed-uuid-adsbexchange | Path to UUID file |
-e MLAT_CLIENT_STATS_JSON= | (none) | Path for stats JSON output |
-e MLAT_CLIENT_PRIVACY= | false | Hide receiver on coverage maps |
-e MLAT_CLIENT_NO_UDP= | false | Disable UDP transport |
-e MLAT_CLIENT_AUTO_LOCATION= | true | Auto-detect lat/lon via IP geolocation when not explicitly set |
-e MLAT_CLIENT_AUTO_ALT= | true | Auto-detect altitude via terrain elevation when lat/lon are available but alt is not set |
-e MLAT_CLIENT_LOG_TIMESTAMPS= | true | Print timestamps in logs |
-e MLAT_CLIENT_ARGS= | (none) | Raw arguments (overrides individual env vars) |
-e MLAT_CLIENT_USER= | root | Runtime user for the container |
-e PUID=911 | 911 | User ID for non-root operation |
-e PGID=911 | 911 | Group ID for non-root operation |
| Volume | Description | Required |
|---|---|---|
-v /config | Configuration and persistent data | Recommended |
Environment variables are set using -e flags in docker run or the environment: section in docker-compose.
You can configure the mlat-client in two ways:
Individual environment variables (recommended): Set MLAT_CLIENT_LAT, MLAT_CLIENT_LON, etc. The container service script assembles the command-line arguments.
Raw arguments: Set MLAT_CLIENT_ARGS to the full argument string. This overrides the individual environment variables.
When MLAT_CLIENT_AUTO_LOCATION is true (the default) and MLAT_CLIENT_LAT/MLAT_CLIENT_LON are not set, the container will automatically detect your approximate latitude and longitude using IP-based geolocation via ip-api.com.
MLAT_CLIENT_LAT/MLAT_CLIENT_LON values always take priorityMLAT_CLIENT_AUTO_LOCATION=false to disable this feature entirelyNote: IP-based geolocation is approximate (typically city-level accuracy). For best MLAT results, set your exact coordinates manually.
Example — auto-detect location:
environment:
- MLAT_CLIENT_AUTO_LOCATION=true # default, can be omitted
# MLAT_CLIENT_LAT, MLAT_CLIENT_LON, MLAT_CLIENT_ALT left unset
- MLAT_CLIENT_USER_ID=myuser
- MLAT_CLIENT_SERVER=feed.adsbexchange.com:31090
- MLAT_CLIENT_INPUT_CONNECT=readsb:30005
- MLAT_CLIENT_RESULTS=beast,connect,readsb:30104
When MLAT_CLIENT_AUTO_ALT is true (the default) and MLAT_CLIENT_ALT is not set, the container will automatically detect your ground elevation using the Open-Meteo Elevation API. This works with both auto-detected and explicitly provided coordinates.
0m on failureMLAT_CLIENT_ALT always takes priorityMLAT_CLIENT_AUTO_ALT=false to disable this featureNote on altitude: The auto-detected altitude represents ground elevation at the detected coordinates, not your antenna height above sea level. For accurate MLAT, your altitude should include the height of your antenna above ground. For example, if ground elevation is
50mand your antenna is on a10mrooftop mast, setMLAT_CLIENT_ALT=60m. When relying on auto-detection, consider adding your antenna height manually for better multilateration accuracy.
Example — explicit lat/lon with auto-detected altitude:
environment:
- MLAT_CLIENT_LAT=51.5
- MLAT_CLIENT_LON=-0.1
# MLAT_CLIENT_ALT left unset — auto-detected from terrain elevation
- MLAT_CLIENT_AUTO_ALT=true # default, can be omitted
- MLAT_CLIENT_USER_ID=myuser
- MLAT_CLIENT_SERVER=feed.adsbexchange.com:31090
- MLAT_CLIENT_INPUT_CONNECT=readsb:30005
- MLAT_CLIENT_RESULTS=beast,connect,readsb:30104
The MLAT_CLIENT_RESULTS variable accepts output specifications in the format:
format,type,address:port
Common examples:
| Results Value | Description |
|---|---|
beast,connect,readsb:30104 | Beast format, connect to readsb on port 30104 |
beast,listen,30105 | Beast format, listen on port 30105 |
basestation,listen,31003 | SBS/BaseStation format, listen on port 31003 |
beast,connect,localhost:30104 | Beast format, connect to localhost |
By default, this container runs as root.
Root mode (default):
PUID or PGID neededNon-root mode (advanced):
MLAT_CLIENT_USER to your usernamePUID and PGID values911:911 if omittedThe container runs mlat-client, connecting to a Beast-format data source and forwarding Mode S messages to a multilateration server.
Common environment variable combinations:
# Standard ADSBexchange feed
-e MLAT_CLIENT_INPUT_CONNECT=readsb:30005
-e MLAT_CLIENT_SERVER=feed.adsbexchange.com:31090
-e MLAT_CLIENT_RESULTS=beast,connect,readsb:30104
# Custom MLAT server with privacy
-e MLAT_CLIENT_SERVER=mlat.myserver.com:31090
-e MLAT_CLIENT_PRIVACY=true
# With UUID file for persistent identity (default: /config/feed-uuid-adsbexchange)
-e MLAT_CLIENT_UUID_FILE=/config/feed-uuid-adsbexchange
# With statistics output
-e MLAT_CLIENT_STATS_JSON=/config/mlat-client/stats.json
For all available options, see the mlat-client documentation.
Check logs:
docker logs mlat-client
docker logs mlat-client --tail 50 -f # Follow last 50 lines
Common causes:
MLAT_CLIENT_LAT, MLAT_CLIENT_LON, MLAT_CLIENT_ALT, and MLAT_CLIENT_USER_ID are set (or leave LAT/LON/ALT empty with MLAT_CLIENT_AUTO_LOCATION=true to auto-detect via IP)m (metres) or ft (feet), e.g. 50m or 160ftMLAT_CLIENT_ARGS syntaxVerify the Beast data source is reachable:
docker exec mlat-client nc -zv readsb 30005
If connection fails:
Verify server connectivity:
docker exec mlat-client nc -zv feed.adsbexchange.com 31090
If connection fails:
If the client connects but no positions are resolved:
LAT/LON/ALT) is accuratedocker logs -f mlat-clientThis project uses semantic versioning:
latest, and architecture-specificUpdate to latest:
docker pull blackoutsecure/mlat-client:latest
docker-compose up -d # if using compose
Check image version:
docker inspect -f '{{ index .Config.Labels "build_version" }}' blackoutsecure/mlat-client:latest
Get help:
docker logs mlat-client # View container logs
docker exec -it mlat-client /bin/bash # Access container shell
docker inspect blackoutsecure/mlat-client # Check image details
Sponsored and maintained by Blackout Secure
Upstream project: wiedehopf/mlat-client Container patterns: LinuxServer.io
| Resource | Link |
|---|---|
| Docker Hub | blackoutsecure/mlat-client |
| Balena Hub | mlat-client block |
| GitHub Issues | Report bugs or request features |
| GitHub Releases | Download releases |
| Resource | Link |
|---|---|
| mlat-client | wiedehopf/mlat-client |
| mlat-server | wiedehopf/mlat-server |
| readsb | wiedehopf/readsb |
| LinuxServer.io | linuxserver.io |
This project is licensed under the GNU General Public License v3.0 or later - see the LICENSE file for details.
The mlat-client application itself is also licensed under GPL-3.0-or-later. For more information, see the mlat-client repository.
Made with ❤️ by Blackout Secure
Content type
Image
Digest
sha256:a1a916f9a…
Size
31.8 MB
Last updated
3 months ago
docker pull blackoutsecure/mlat-client:sha-38d3b30d90ac