If my notes
are correct I've been running an ADS-B feeder for over 10 years (with over
7 years of uptime currently) and so when I ran across
ACARS DRAMA recently I was immediately interested in
running my own feeder. The provided
instructions
include a medium post
and some sample configurations but are otherwise quite sparse. The general
gist seems to be that the canonical method of building a feeder is to run a
stack of containers that largely serve to just ship around an unnecessary copy
of a Linux distribution and spawn a whole bunch of processes via their own
init replacements and trust-me bash scripts. Dear reader you may be absolutely
shocked to find out that I am not interested in living that particular life,
so I set about gutting the mess and building my own version of the stack that
runs directly on the host operating system, taking advantage of security
updates, shared libraries, and the other modern conveniences of a decent Linux
distribution (Debian, in my case).
Containers
If you will allow me a brief digression, I'll freely admit that I found myself enamored early on by some of the portability and sandboxing advantages offered by containerization systems, it has however — along with the "modern" packaging formats like Flatpak and snap gone way off the rails. Instead of being a convenient way to develop applications to run across clouds it seems to have become some sort of sick replacement for distribution packages, especially in the hobbyist / enthusiast space. Containers seem even more egregious in their sins than the packaging formats because most of them ship Linux distribution's userspace (usually either Alpine or Debian) along with the binaries, libraries and resource files that the application needs instead of building a well structured, portable application that can use the libraries and services provided by the operating system. You end up having to rely on the application developer for what should rightly be operating system managed security updates. Add in the modern development model which is increasingly likely to include a graph of hundreds of un-audited dependencies gotten from central code repositories like npm, crates.io, pypi, or just github the general ecosystem has gotten dire. Don't get me started on the "burn our custom .img file on a micro SD card for your Raspberry Pi and Trust Us" model. In the end the sandboxing may help, sure, but who is cleaning it?
They're for building, not packaging
Initially I was intending to convert the pile of parts into native Debian packages. This would result in a much lighter weight installation and allow for more modular maintenance and allow me to use the Debian project's package building mechanisms. As I looked at the software, the SDR decoders (acarsdec and dumpvdl2) looked straightforward enough, however; acars_router is written in Rust 🤮 and acarshub is distributed only as a Docker container pre-loaded with Python and TypeScript webapp. Those were going to prove to be more difficult or at least more tedious to package so I decided take another path. The easiest solution ended up being to write a Makefile and Dockerfile that fetches, builds and then creates a tarball of all the bits and pieces that I need. While it takes a while on a Raspberry Pi 3B to build everything it at least works and the resultant archive is only around 12 megabytes, instead of the ~296 megabytes that the container stack consumes. Thankfully it ended up being fairly straightforward to patch acarshub to work outside of Docker, and I didn't have to install any packages that weren't available in the Debian 13 (trixie) package repository.
Wrestling Ansible
Armed with a bundle of built artifacts I need to actually get them on
a system and plumbed together, since I manage my Raspberry Pi systems with
Ansible I started crafting a
playbook
and associated support files. The biggest difficulty was getting all the
pieces right with acarshub, it's a bit of a mess seeing as it appears that
the developers only intended it to be distributed as a built container. On top
of the patches I had to apply at build time I created systemd units, a few
helper scripts, and custom Apache configuration to replace the mess of scripts
and Dockerfile nonsense that was previously wrapped together. The funny part
is that once I got all this up and working I discovered that it's essentially
entirely optional. If you are looking to just feed data to one of the central
servers like acarsdrama.com, you can do so by just specifying the proper
arguments to acars_router to send your streams to the upstream destination
of your choice.

After some tweaking I was able to get things working pretty well, even on the anemic Raspberry Pi 3B that I use for testing. I hooked the SDR's input up to the discone antenna in my attic that I use for other scanner applications and things came alive.
Lessons Learned
While interesting to watch one of the things that has become clear is that the acarshub web UI is unnecessary, much like the skyview portion of the ADS-B/UAT feeder I have. If all you are looking to do is provide a feed up to the Internet, then all you need are the SDR decoders feeding acars_router.

Most of the patches
I wrote could probably be cleaned up and submitted upstream though I don't
think the developer cares about running the application outside of a container
(there is rudimentary support for this in the form of a LOCAL_TEST
environment variable). I may take the time to go back and create Debian
packages for the libacars / acarsdec / dumpvdl2 pieces and simplify the build
process I have.
What's Next
I'm in the process of relocating some antennas onto a single mast on my roof so it will be reasonable to add a dedicated VHF airband antenna to the wideband discone, ADS-B and UAT antennas. Then I can build a dedicated, reliable feeder appliance along side the next hardware revision of my ADS-B / UAT feeder. I should have more about that process come spring when I feel like braving the roof.
Most of you will probably scoff at all this and will just run the recommended
docker-compose.yml stack or the pre-built Raspberry Pi image but I put this
here in hopes that this helps one or two of you, or even serves as a basis for
some future project. If you take nothing else from this, allow me to poorly
quote Antoine de Saint Exupéry ... perfection is finally attained not when
there is no longer anything to add, but when there is no longer anything to
take away...
; simplicity should be the goal.
As I expect this to be the last post of the year, may 2025 pass quietly and 2026 bring joy.
Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.