Feeding multiple ADS-B networks at once with Docker and Ultrafeeder

One container decodes, many networks get the data: How to set up the sdr-enthusiasts Ultrafeeder, add community networks via ULTRAFEEDER_CONFIG and attach FlightAware, Flightradar24 and others as their own containers.

Planetrack editorial teamPublished: October 15, 202614 min read

Key takeaways

  • One container as the centerpiece: Ultrafeeder bundles readsb as the decoder, tar1090 as the map, graphs1090 for statistics and one mlat-client per MLAT server.
  • Community networks one line at a time: You add adsb.fi, adsb.lol, airplanes.live and others in the ULTRAFEEDER_CONFIG variable – one line for data and one for MLAT.
  • Commercial services as companion containers: FlightAware, Flightradar24, AirNav Radar and Plane Finder run in their own containers, which fetch their data from the centerpiece with BEASTHOST=ultrafeeder.
  • All settings in one place: Coordinates, altitude, keys and UUIDs live in an .env file, the services in a docker-compose.yml.
  • One UUID per network: The sdr-enthusiasts guide advises separate UUIDs so your station can’t be recognized across networks.
Contents
  1. 1.The short answer
  2. 2.Why Docker for an ADS-B receiver?
  3. 3.What is inside Ultrafeeder
  4. 4.Preparation: hardware and host system
  5. 5.Project folder and .env file
  6. 6.The docker-compose.yml with Ultrafeeder
  7. 7.Commercial networks as their own containers
  8. 8.MLAT with multiple networks
  9. 9.Operation: logs, updates, health
  10. 10.Who the switch is worth it for
  11. 11.Conclusion

First PiAware, then fr24feed, then the script for adsb.fi and another one for adsb.lol – if you let your receiver grow over the years, you eventually end up with a system full of services, configuration files and dependencies. The sdr-enthusiasts community takes a different path: A single Docker container called Ultrafeeder handles decoding, map, statistics and all community feeds, and every further network joins as its own cleanly separated container. This guide shows you how to feed multiple ADS-B networks at once with Ultrafeeder, which files you need and how to keep track of everything.

From the receiver straight to the sighting

With Planetrack, you log every sighting with photo, registration, type, airline, airport and spot – and sighting alerts tell you when a registration you follow is on approach. Planetrack is launching soon – join the waitlist and get early access.

Download Planetrack on the App Store Get Planetrack on Google Play

The short answer

You feed multiple networks at once by installing Docker on a Linux computer and creating a docker-compose.yml with the Ultrafeeder container as the hub. Ultrafeeder reads your SDR stick, decodes the signals with readsb and sends the data to all the community networks you enter in the ULTRAFEEDER_CONFIG variable. Commercial services such as FlightAware or Flightradar24 you attach as additional containers, which get their data from the hub via BEASTHOST=ultrafeeder. Coordinates, altitude and keys are collected in one .env file.

The principle is the same as with the individual scripts from Feeding ADS-B Exchange and community networks: One decoder produces a data stream, several feeders tap into it. Only that with Docker, each building block runs in its own capsule.

1Container for decoder, map, statistics and all community feeds
8080Port of the tar1090 map in the sdr-enthusiasts example setup
2Lines per community network: data and MLAT

Why Docker for an ADS-B receiver?

In their guide, the sdr-enthusiasts justify their approach with several points that are immediately tangible for spotters with a growing feeder zoo:

  • Isolation: Every container brings its own software. Different library versions don’t get in each other’s way, and the host system stays clean.
  • Easy expansion: A new network means one more container or two lines of configuration – no worry that an installation script overwrites something.
  • Central configuration: Instead of maintaining files under /etc/default/ and in various program folders, everything is in the Compose file and the .env file.
  • Shared hardware: The computer can carry other services on the side. That saves an additional device and power.

The price: You should know a few Docker basics or be willing to learn them. If you only want to feed one network and already have a Pi running, you often reach the goal faster with the classic packages. An overview of all variants is given in ADS-B feeder programs compared.

What is inside Ultrafeeder

Ultrafeeder is not a new program but a carefully assembled package of proven open-source tools:

Component Job
readsb Decodes the SDR stick’s signals and distributes the data over network ports
tar1090 Map interface in the browser, including replay, tracks of the last 24 hours and heatmap
graphs1090 Charts on message rate, range, signal strength and system load
mlat-client One instance per MLAT server entered
MLAT hub Merges calculated MLAT positions from several sources
Autogain Regulates the RTL-SDR’s gain; the built-in variant from readsb is recommended

If you already know readsb and tar1090, you will find your way around right away – the interfaces are the same as in Installing readsb and tar1090. The only new thing is that everything runs in one container and is controlled via environment variables.

Preparation: hardware and host system

For hardware, you need the usual: a computer, an SDR stick and a 1090 MHz antenna. Which stick is suitable is covered in SDR sticks for ADS-B compared, and you build the antenna following Building a 1090 MHz antenna yourself. The computer doesn’t have to be a Raspberry Pi; the sdr-enthusiasts guide is aimed at Debian-based systems such as Raspberry Pi OS, Ubuntu or DietPi. Possible alternatives to the Pi are described in ADS-B reception without a Raspberry Pi.

For the host system, the project provides an installation script that sets up Docker and the Compose plugin, adjusts the udev rules for RTL-SDR sticks and blocks the preinstalled kernel drivers for the sticks so the containers can access the stick:

bash <(curl -s https://raw.githubusercontent.com/sdr-enthusiasts/docker-install/main/docker-install.sh)

As always with scripts from the internet: Read it first. The project itself recommends exactly that.

Renaming the stick

Almost all RTL-SDR sticks come from the factory with the same serial number. So that the container finds the right stick – at the latest when a second one for airband or UAT is added – you assign a unique serial number. The recommendation is 1090 for the ADS-B stick. To do this, you plug in only this one stick and write the number with rtl_eeprom from the Ultrafeeder image:

docker run --rm -it --device /dev/bus/usb --entrypoint rtl_eeprom ghcr.io/sdr-enthusiasts/docker-adsb-ultrafeeder -s 1090

After confirming, you unplug the stick and plug it back in. According to the guide, rebooting the computer is not enough.

Note down coordinates and altitude now

For MLAT, you need latitude, longitude and the antenna’s height above sea level as precisely as possible – terrain height plus mounting height. A mast on the roof is easily ten meters above the ground. You enter these values once centrally in a moment and use them for all networks.

Project folder and .env file

The guide puts everything under /opt/adsb. The Compose file and a hidden .env file with your master data live there:

sudo mkdir -p -m 777 /opt/adsb
cd /opt/adsb
nano .env

The .env should contain these values, among others:

FEEDER_LAT=48.1234567
FEEDER_LONG=11.1234567
FEEDER_ALT_M=520
FEEDER_TZ=Europe/Berlin
FEEDER_NAME=meine-station
ADSB_SDR_SERIAL=1090
ADSB_SDR_PPM=
ULTRAFEEDER_UUID=

The numbers are placeholders – enter your own values. FEEDER_NAME is later transmitted to the networks as the MLAT name; choose it so that you can live with it showing up publicly. You generate a UUID with:

cat /proc/sys/kernel/random/uuid

Important for privacy: The guide warns against using the same UUID for all networks, because your station would then be recognizable across services. So generate a separate UUID per network and save it under descriptive names such as ADSBFI_UUID or ADSBLOL_UUID in the .env.

Spotted a rarity on your map?

With Planetrack, you set up sighting alerts for registrations, types, airlines and special liveries and find out when they are on approach or landing. Planetrack is launching soon – join the waitlist and get early access.

Download Planetrack on the App Store Get Planetrack on Google Play

The docker-compose.yml with Ultrafeeder

Now comes the centerpiece. An abridged example, based on the sdr-enthusiasts guide, with two community networks:

services:
  ultrafeeder:
    image: ghcr.io/sdr-enthusiasts/docker-adsb-ultrafeeder
    container_name: ultrafeeder
    hostname: ultrafeeder
    restart: unless-stopped
    device_cgroup_rules:
      - "c 189:* rwm"
    ports:
      - 8080:80
    environment:
      - LOGLEVEL=error
      - TZ=${FEEDER_TZ}
      - READSB_DEVICE_TYPE=rtlsdr
      - READSB_RTLSDR_DEVICE=${ADSB_SDR_SERIAL}
      - READSB_RTLSDR_PPM=${ADSB_SDR_PPM}
      - READSB_GAIN=auto
      - READSB_LAT=${FEEDER_LAT}
      - READSB_LON=${FEEDER_LONG}
      - READSB_ALT=${FEEDER_ALT_M}m
      - UUID=${ULTRAFEEDER_UUID}
      - MLAT_USER=${FEEDER_NAME}
      - ULTRAFEEDER_CONFIG=
          adsb,feed.adsb.fi,30004,beast_reduce_plus_out,uuid=${ADSBFI_UUID};
          mlat,feed.adsb.fi,31090,uuid=${ADSBFI_UUID};
          adsb,in.adsb.lol,30004,beast_reduce_plus_out,uuid=${ADSBLOL_UUID};
          mlat,in.adsb.lol,31090,uuid=${ADSBLOL_UUID}
    volumes:
      - /opt/adsb/ultrafeeder/globe_history:/var/globe_history
      - /opt/adsb/ultrafeeder/graphs1090:/var/lib/collectd
      - /proc/diskstats:/proc/diskstats:ro
      - /dev/bus/usb:/dev/bus/usb:rw
    tmpfs:
      - /run:exec,size=256M

Docker Compose reads the values in ${...} automatically from the .env in the same folder. The tmpfs entry puts volatile data in RAM and so spares the SD card. The paths under volumes make sure map history and statistics survive a container restart. You will find the complete, current template with all optional variables in the guide and in the project’s GitHub repository – when in doubt, use their version.

How to read ULTRAFEEDER_CONFIG

Every entry begins with a type:

  • adsb,<host>,<port>,<protocol> sends your ADS-B data to a server or fetches data from a source. For most newer networks, the project recommends the beast_reduce_plus_out protocol, a slimmed-down Beast format.
  • mlat,<host>,<port> starts a separate mlat-client instance for this server.
  • mlathub,<host>,<port>,<protocol> accepts MLAT results from other feeders and merges them.

Optionally, you append uuid=.... If it is missing, the container uses the general UUID variable. Entries are separated by semicolons, and within an entry, neither additional semicolons nor commas may appear in values.

Network Data (host, port) MLAT (host, port)
adsb.fi feed.adsb.fi, 30004 feed.adsb.fi, 31090
adsb.lol in.adsb.lol, 30004 in.adsb.lol, 31090
airplanes.live feed.airplanes.live, 30004 feed.airplanes.live, 31090
Planespotters feed.planespotters.net, 30004 mlat.planespotters.net, 31090
ADS-B Exchange feed1.adsbexchange.com, 30004 feed.adsbexchange.com, 31090

The addresses come from the README of the Ultrafeeder project, as of October 2026. It lists further, partly regional networks. Because hostnames can change, check them against the current list before entering them. Which of these maps shows what is compared in Unfiltered community trackers compared, and background on ADS-B Exchange is provided in ADS-B Exchange explained.

Starting and checking

You start it in the project folder with:

docker compose up -d

After a minute or two, you open http://<ip-of-your-computer>:8080/ in the browser. The tar1090 map with your reception appears there. Useful additions are /graphs1090/ for the statistics as well as the parameters ?pTracks for the tracks of the last 24 hours, ?heatmap for a heatmap and ?replay for replay. What the charts reveal about your antenna is explained in Measuring reception performance with graphs1090.

Commercial networks as their own containers

FlightAware, Flightradar24 and other commercial services require their own feeder programs with keys. For these too, the sdr-enthusiasts offer ready-made images. The pattern is always the same: The container gets BEASTHOST=ultrafeeder, fetches the data stream from the hub that way and logs in to the service with your key from the .env.

Service Image Key variable Local interface in the example
FlightAware ghcr.io/sdr-enthusiasts/docker-piaware FEEDER_ID Port 8081 (SkyAware)
Flightradar24 ghcr.io/sdr-enthusiasts/docker-flightradar24 FR24KEY Port 8754
AirNav Radar ghcr.io/sdr-enthusiasts/docker-airnavradar SHARING_KEY –
Plane Finder ghcr.io/sdr-enthusiasts/docker-planefinder SHARECODE Port 30053

The guide also has instructions for the OpenSky Network, ADSBHub, Plane.watch, RadarVirtuel and further networks. An example for FlightAware looks like this:

  piaware:
    image: ghcr.io/sdr-enthusiasts/docker-piaware:latest
    container_name: piaware
    restart: unless-stopped
    ports:
      - 8081:8080
    environment:
      - BEASTHOST=ultrafeeder
      - MLAT_RESULTS_BEASTHOST=ultrafeeder
      - MLAT_RESULTS_BEASTPORT=31004
      - TZ=${FEEDER_TZ}
      - FEEDER_ID=${PIAWARE_FEEDER_ID}
    tmpfs:
      - /run:exec,size=64M
      - /var/log

The two MLAT_RESULTS lines feed the MLAT positions calculated by FlightAware back into Ultrafeeder’s MLAT hub so that they also appear on your local map.

Carrying over keys or generating new ones

This is the most important pitfall when migrating: If you already feed, carry over your existing keys. Otherwise, the service creates a new station, and statistics and the feeder rewards stay with the old one. The guides give the commands for existing installations:

  • FlightAware: piaware-config -show feeder-id on the old system. New feeders can be registered once via a temporary container and then assigned to an account on flightaware.com. Make sure position and altitude at FlightAware match your .env, otherwise MLAT doesn’t work. More on FlightAware itself is in Installing and setting up PiAware.
  • Flightradar24: The sharing key is in the old /etc/fr24feed.ini. New feeders run the signup dialog in a temporary container. Background is provided in Setting up fr24feed.
  • AirNav Radar: rbfeeder --showkey --no-start or a look at /etc/rbfeeder.ini shows the old key. Without a key, the container generates a new one on first start and prints it in the log. More on the service itself is in Using AirNav RadarBox.
  • Plane Finder: You find the share code in your account on planefinder.net under your receivers. An overview of the service is given in Plane Finder at a glance.

You switch off the old feeders on the host system before the containers take over – otherwise two programs report with the same key. Which subscriptions and benefits the services grant you for feeding is compared in What feeders get in return.

MLAT with multiple networks

Every mlat line in ULTRAFEEDER_CONFIG starts its own mlat-client. Your station thereby takes part in the multilateration of every network entered – and each network calculates with the stations that take part there. The more networks you supply, the greater the chance that at one of them enough neighbors are within range. Military aircraft without their own position reports in particular only show up then; how the method works is covered in MLAT/multilateration.

The requirements are the same as for any other installation: exact coordinates, correct antenna height and stable reception. The advantage of Docker: These values are in the .env only once and automatically apply to all networks. Typos in individual configuration files that knock out MLAT at one network but not another no longer happen that way.

Operation: logs, updates, health

In everyday use, you get by with a few commands that you run in the /opt/adsb folder:

Task Command
Follow all logs live docker compose logs -f
Log of one container docker logs -f ultrafeeder
Status and health docker ps
Apply changes to .env or Compose docker compose up -d
Update all images docker compose pull, then docker compose up -d

The sdr-enthusiasts containers come with health checks. In the STATUS column of docker ps, you then see healthy, unhealthy or health: starting. If a container permanently shows unhealthy, its log usually gives you the reason – often a wrong key, a stick that wasn’t found or a typo in ULTRAFEEDER_CONFIG.

Symptom Likely cause Solution
Map empty, log reports no device Wrong serial number or stick occupied by another program Check serial number, stop the old decoder on the host
One network gets no data Typo or missing semicolon in ULTRAFEEDER_CONFIG Compare the entry with the project list, docker compose up -d
FlightAware container unhealthy Feeder ID missing or location at FlightAware differs Check ID in .env, align position in the account
Duplicate station at one service New key used instead of the old one Enter the old key in .env, recreate the container

For advanced users, the guide also describes automatic updates, automatic restart of unhealthy containers and analysis with Grafana. You don’t need any of that to get started.

Who the switch is worth it for

Ultrafeeder fits if …

  • you want to supply three or more networks at the same time
  • the computer carries other services too
  • you want all settings in one place

Weigh it up if …

  • your existing Pi with individual scripts runs stably
  • you have never used Docker
  • you only work on the system occasionally

Probably not if …

  • you only feed a single network
  • you prefer to operate a ready-made image through a web interface
  • the computer is very short on memory

For spotting practice, a well-fed receiver brings a very tangible advantage: Your region is covered more densely on several maps, often exactly where you spot yourself – for example at the Munich Airport visitors’ hill with a view of Munich Airport or at the Teveren spotters’ hill, where NATO’s AWACS fleet is stationed. On top come tools with which you can later work out what really flew past; how to do that is shown in Matching sightings with ADS-B logs. Whether receiving and passing on the data is allowed in your country is clarified in Receiving ADS-B data: the legal situation.

Is your Ultrafeeder setup complete?

Check off what is done on your end – at the end you will see whether your station is running smoothly.

  • Docker and the Compose plugin are installed, the stick has serial number 1090.
  • Coordinates and antenna height are entered exactly in the .env.
  • Every network has its own UUID.
  • The tar1090 map on port 8080 shows aircraft.
  • All containers report the status healthy in docker ps.
  • Existing keys for FlightAware, Flightradar24 and others are carried over, old feeders on the host stopped.

Turning data into sightings

Post your sightings with photo, registration and airport in Planetrack, collect them in the hangar with a wish list and exchange ideas with the community. Planetrack is launching soon – join the waitlist and get early access.

Download Planetrack on the App Store Get Planetrack on Google Play

Conclusion

With the sdr-enthusiasts Ultrafeeder, a feeder jumble that has grown over time becomes a tidy system: one container for decoder, map, statistics and all community networks, plus a lean container for each commercial service. As always, the master data deserves the most care – coordinates, altitude, keys and separate UUIDs. Once the .env is in place, each further network is a matter of two lines and a docker compose up -d.

In short

Install Docker, rename the stick to 1090, put master data in the .env, start Ultrafeeder with all community networks in ULTRAFEEDER_CONFIG and attach commercial services as companion containers with BEASTHOST=ultrafeeder and your existing keys. A separate UUID per network protects your privacy.

Summary

  • The sdr-enthusiasts project provides ready-made Docker images for receiving, decoding and passing on ADS-B data, documented in a freely accessible guide.
  • The Ultrafeeder container handles the SDR stick, decoding, map interface, statistics and all community feeds including MLAT.
  • For commercial networks, you start one more container from the same family each and only enter the respective key.
  • Updates, logs and restarts run for all services through the same Docker Compose commands.

Frequently asked questions

What is Ultrafeeder?

Ultrafeeder is a Docker container from the community project sdr-enthusiasts. It combines the readsb decoder, the tar1090 map interface, graphs1090 statistics, mlat-client for multilateration and an MLAT hub that merges calculated positions from several sources. That way, it replaces installing all of these programs individually on the computer.

Do I need a Raspberry Pi for Ultrafeeder?

Not necessarily. The containers run on Debian-based Linux systems such as Raspberry Pi OS, Ubuntu or DietPi. That can be a Raspberry Pi, but also another single-board computer or a small PC that carries further services on the side. What matters is a USB port for the SDR stick.

How do I add another community network?

You add two lines to the ULTRAFEEDER_CONFIG variable: an adsb line with host, port and protocol, such as adsb,feed.adsb.fi,30004,beast_reduce_plus_out;, and an mlat line with host and port, such as mlat,feed.adsb.fi,31090;. Each line ends with a semicolon. Afterward, docker compose up -d applies the change.

How do I connect FlightAware or Flightradar24?

Through their own sdr-enthusiasts containers, such as docker-piaware and docker-flightradar24. Both get the BEASTHOST=ultrafeeder variable and your key from the .env file: the feeder ID for FlightAware and the sharing key for Flightradar24. If you already feed, you carry over the existing values so statistics and rewards are preserved.

Why should I use a separate UUID for each network?

The UUID identifies your station to the network operator. If you use the same one everywhere, your station could be recognized across several services. The sdr-enthusiasts guide therefore recommends a separate UUID for each network. On Linux, you generate a new one with cat /proc/sys/kernel/random/uuid.

Where do I see whether everything is running?

With docker ps, you see all containers with a health status such as healthy or unhealthy. You read the logs with docker compose logs -f for all or docker logs -f ultrafeeder for a single container. You reach the map in the browser on port 8080 and the statistics under the path /graphs1090/.

Can I run Ultrafeeder alongside an existing readsb installation?

An SDR stick can only be used by one program at a time. Either Ultrafeeder takes over the stick and you disable the old decoder, or you leave READSB_DEVICE_TYPE empty and feed Ultrafeeder from the existing decoder via a beast_in connection. For a clean rebuild, the first variant is easier to follow.

PT

Planetrack editorial team

We build the Planetrack app and go spotting ourselves – on observation decks, under approach paths and at the fence. Every guide is based on our own experience and is updated regularly.

More articles in ADS-B, MLAT & receivers →

Read more in ADS-B, MLAT & receivers

Related airports & manufacturers

Airports, manufacturers, airline groups and alliances – who is behind them and what you should know as a spotter.

All airports & manufacturers →

Related spotting locations

Specific vantage points with the runway configuration, light times, coordinates and an honest take on whether the trip is worth it.

All spotting locations at a glance →

← Back to the blog