- Docker-Planefence
This repository contains Planefence, which is an add-on to ultrafeeder, readsb, dump1090, or dump1090-fa (referred to herein as your Feeder Station).
Planefence will create a log of aircraft heard by your Feeder Station that are within a "fence", that is, less than a certain distance and lower than a certain altitude from your station. This log is displayed on a website and is also made available in daily CSV files. Furthermore, Planefence can send a notification for every plane in the fence to BlueSky, Mastodon, Discord, Telegram, RSS, and/or MQTT. We used to support Twitter/X as well but this was deprecated when they started charging for API use. With some add-on software/hardware, you will be able to collect audio noise figures to see how loud the aircraft are that fly above your Feeder Station.
Planefence is deployed as a Docker container and is pre-built for the following architectures:
- linux/ARMv7 (armhf): Raspberry Pi 3B+ / 4B with 32-bits Debian 10 Linux or later (RaspOS, Armbian, DietPi, etc.)
- linux/ARM64: Raspberry Pi 4B/5 with 64-bits Debian OS 10 or later (RaspOS, Armbian, DietPi, Ubuntu, etc.)
- linux/AMD64: 64-bits PC architecture (Intel x86 or AMD) running Debian 10 Linux or later (incl. Ubuntu)
The Docker container is available at ghcr.io/sdr-enthusiasts/docker-planefence and can be pulled directy using this Docker command: docker pull ghcr.io/sdr-enthusiasts/docker-planefence.
Here are some assumptions or prerequisites:
- You are already familiar the
dump1090family of ADS-B software (for example,ultrafeeder,readsb,tar1090,dump1090, ordump1090-fa), how to deploy it, and the hardware needed. Ideally, you have your ADS-B station already up and running. - You know how to deploy Docker images to your machine. If you don't -- it's actually quite simple. It makes installation of new components really easy. Mikenye's excellent Gitbook contains a step-by-step guide, and the quick install script can help you get started.
- You use
docker compose. This README has been written assumingdocker compose. If you don't have it, feel free toapt-get installit. It should be easy to convert thedocker-compose.ymlinstructions to a command-linedocker runstring, but you are on your own to do this. - Further support is provided at the #planefence channel at the SDR Enthusiasts Discord Server. If you need immediate help, please tag "@k1xt" to your message.
There must already be an instance of ultrafeeder, tar1090, dump1090[-fa], or readsb connected to a SDR somewhere in reach of your Planefence machine:
- This could be in the same stack of containers, separately on the same machine, or even on another machine.
- It is important to enable SBS data on port 30003 on that instance. Planefence will use this to get its data. See the Troubleshooting section for help to get this done.
-
If you are adding this to an existing stack of Docker containers on your machine, you can add the information from this project to your existing
docker-compose.yml. Example data is available in this file. -
If you are not adding this to an existing container stack, you should create a project directory:
sudo mkdir -p -m 0777 /opt/planefence sudo chmod a+rwx /opt/planefence cd /opt/planefence -
Important — if you are using adsb.im, you MUST put Planefence in its own directory, like
/opt/planefence. You should never add it to an existing stack. -
Then add the template
docker-compose.ymlfile from here:curl -s https://raw.githubusercontent.com/sdr-enthusiasts/docker-planefence/main/docker-compose.yml > docker-compose.yml
In the docker-compose.yml file, you should configure the following:
- IMPORTANT: Update
TZ=America/New_Yorkto whatever is appropriate for you. Note that this variable is case sensitive - There are 2 volumes defined. My suggestion is NOT to change these unless you know what you are doing
- After you exit the editor, start the container (
docker compose up -d). The first time you do this, it can take a minute or so. - Monitor the container (
docker logs -f planefence). At first start-up, it should be complaining about not being configured. That is expected behavior. - Once you see the warnings about
planefence.confignot being available, press CTRL-C to get the command prompt.
The remainder of this document will assume that you used the port and volume mappings as they are described in docker-compose.yml. If you change those, you should replace some of the port and directory values with your changed values.
If you have mapped the :9999 container port as described in the docker-compose.yml file, you can browse to http://localhost:9999 to configure Planefence.
You can change data in all the tabs (make sure to at least configure the options in the Required and General tabs!), and once done, press Save to store the data. At this time, a container restart may be required and the Web page will automatically take care of this.
The configuration file will be stored in ./planefence/config/planefence.config; you can also manually edit this file as described in the next section.
Previous configurations will be stored in ./planefence/config/config-backups, you can use the Restore old config tab to restore them, or manually copy them back in place. Note -- when restoring old configurations, a container restart may be needed. This is NOT done automatically when you restore a configuration.
Although we recommend using the web interface to configure your Planefence options, can also manually configure them by creating and editing a configuration file
-
After you start the container for the first time, it will create a few directories with setup files. You MUST edit these setup files before things will work!
-
MANDATORY: After first start, a file named
planefence.config.RENAME-and-EDIT-meappears in./planefence/config. Copy it toplanefence.config, and then edit that file.cd /opt/planefence cd ./planefence/config # Copy to planefence.config cp planefence.config.RENAME-and-EDIT-me planefence.config # Edit the template # Note - when you are done, save and exit with CTRL-x (and follow the prompts) nano planefence.config
-
IMPORTANT: Review all parameters in
planefence.config; their function is explained in that file. Edit to your liking and save/exit usingCtrl-X. THIS IS THE MOST IMPORTANT AND MANDATORY CONFIG FILE TO EDIT! -
Restart the container to apply your settings:
docker compose up -d planefence --force-recreate
-
OPTIONAL:
nano planefence-ignore.txt. In this file, you can add aircraft that Planefence will ignore. If there are specific planes that fly too often over your home, add them here. Use 1 line per entry, and the entry can be a ICAO, flight number, etc. You can even use regular expressions if you want. Be careful -- we use this file as an input to a "grep" filter. If you put something that is broad (.*for example), then ALL PLANES will be filtered out. -
OPTIONAL:
nano airlinecodes.txt. This file maps the first 3 characters of the flight number to the names of the airlines. We scraped this list from a Wikipedia page, and it is by no means complete. Feel free to add more to them -- please add an issue at https://github.com/sdr-enthusiasts/docker-planefence/issues so we can add your changes to the default file. -
OPTIONAL: If you have multiple containers running on different web port, and you would like to consolidate them all under a single host name, then you should consider installing a "reverse web proxy". This can be done quickly and easily — see the reverse proxy instructions.
-
OPTIONAL: If you have a soundcard and microphone, adding NoiseCapt is as easy as hooking up the hardware and running another container. You can add this to your existing
docker-compose.ymlfile, or run it on a different machine on the same subnet. See the NoiseCapt instructions. -
OPTIONAL: Add screenshots of tar1090 to your notifications in Planefence and Plane-Alert. In order to enable this, simply add the
screenshotsection to yourDocker-compose.ymlfile as per the example in this repo'sdocker-compose.ymlfile. Note - to simplify configuration, Planefence assumes that the hostname of the screenshotting image is calledscreenshotand that it's reachable under that name from the Planefence container stack. -
OPTIONAL: Show OpenAIP overlay on Planefence web page heatmap. Enable this by setting the option
PF_OPENAIP_LAYER=ONinplanefence.config
Generally, any new features will be described in the default/example planefence.config.RENAME-and-EDIT-me file. A raw version of this file can be downloaded here: hhttps://raw.githubusercontent.com/sdr-enthusiasts/docker-planefence/refs/heads/main/rootfs/usr/share/planefence/stage/persist/planefence.config.RENAME-and-EDIT-me. Note - you cannot use this file as-is; you MUST configure the parameters as appropriate for your station.
New features will also appear in the Web Configuration Page as they become available.
In some circumstances you may wish to blacklist certain planes, or types of planes, from appearing in Plane-Alert and its Mastodon and Discord posts. This may be desireable if, for example, you're located near a military flight training base, where you could be flooded with dozens of notifications about T-6 Texan training aircraft every day, which could drown out more interesting planes. To that end, excluding planes can be accomplished using the PA_EXCLUSIONS= parameter in the Configuration Webpage, and in planefence.config. Currently, you may exclude whole ICAO Types (such as TEX2 to remove all T-6 Texans), specific ICAO hexes (e.g. AE1ECB), specific registrations and tail codes (e.g. N24HD or 92-03327), or any freeform string (e.g. UC-12, Mayweather, Kid Rock). Multiple exclusions should be separated by commas. Exclusions are case insensitive and spaces must be escaped with a slash \. An example:
PA_EXCLUSIONS=tex2,AE06D9,ae27fe,Floyd\ Mayweather,UC-12WThis would exclude all T-6 Texans, the planes with ICAO hexes AE06D9 (a Marine Corps UC-12F Huron) and AE27FE (a Coast Guard MH-60T), any planes with "Floyd Mayweather" anywhere in the database entry, and any planes with "UC-12W" anywhere in the database entry. URLs and image links are intentionally not searched.
Please note: this is a powerful feature which may produce unintended consequences. You should verify that it's working correctly by examining the container logs after making changes to planefence.config. You should see, e.g.:
tex2 appears to be an ICAO type and is valid, entries excluded: 479
AE06D9 appears to be an ICAO hex and is valid, entries excluded: 1
ae27fe appears to be an ICAO hex and is valid, entries excluded: 1
Floyd Mayweather appears to be a freeform search pattern, entries excluded: 1
UC-12W appears to be a freeform search pattern, entries excluded: 8
490 entries excluded.
Also note that after adding exclusions, any pre-existing entries for those excluded planes in your Plane Alert web user interface will not be entirely removed, but some fields will disappear. If you've made a mistake and revert your exclusion changes to planefence.config, affected entries in your web user interface will be fully restored after a few minutes.
- Generally, if you make changes in the Web Config Page, the container will be restarted automatically if that's warranted.
- If you restored a back up copy via the Web Config Page, you may have to manually restart the container as described below.
- If you made a bunch of changes for the first time, you should restart the container.
- In the future, most updates to
planefence.configwill be picked up automatically. - Changes to
FEEDER_LAT, ``,PF_SOCK30003HOST, `PF_SOCK30003PORT`, or any of the units related parameters will require a container restart before they become effective. - You can restart the Planefence container by doing:
docker restart planefence
Need the latest image or want to refresh your container?
docker restart planefencepushd /opt/planefence
docker compose pull planefence
docker compose up -d planefence --force-recreate
popdPlanefence logs are always written to the container logs. In addition, you can optionally expose a log web page with the PF_WEBLOGS parameter in planefence.config.
Use Docker logs directly:
docker logs -f planefencePF_WEBLOGS controls where the logs page is exposed:
| Parameter | Values | Description |
|---|---|---|
PF_WEBLOGS |
config (default), main, off, disabled, 0, no |
config: expose logs on the configuration web server. main: expose logs on the main Planefence web server. off/disabled/0/no (case-insensitive): do not expose a logs web page. |
After changing PF_WEBLOGS, restart/recreate the container so lighttpd can apply the listener mapping.
Examples:
- If
PF_WEBLOGS=configandPF_CONFIG_HTTP_PORT=9999:http://myhost:9999/planefence-logs/ - If
PF_WEBLOGS=mainandPF_HTTP_PORT=80:http://myhost/planefence-logs/
- Planefence deployment example: https://planefence.com/planefence-dev
- BlueSky notifications: https://bsky.app/profile/aboveboston.bsky.social
- Telegram notifications: https://t.me/+B_r-DgeNEQ4yMTUx
- RSS feed: https://kx1t.com/planefence-dev/planefence.rss
The Planefence web UI supports additional URL query parameters for selecting data mode, language, and opening specific pages/modals on load.
| Parameter | Values | Description |
|---|---|---|
mode |
pf, planefence, pa, plane-alert, planealert |
Selects the data mode on load. |
lang |
language code such as en-US, nl-NL, es-ES |
Selects the UI language (if available in locales/strings.json). |
page |
info, heatmap, insights |
Opens the corresponding UI page/modal on load. |
page=infoopens Station Info.page=insightsopens Insights.page=heatmapopens Heatmap only in Planefence mode.- If
moderesolves to Plane-Alert,page=heatmapis ignored and the main Plane-Alert view is shown.
You can combine these options:
- Open Insights in Planefence mode:
- Open Station Info in Plane-Alert mode:
- Request Heatmap in Planefence mode:
- Open in Dutch:
Planefence and Plane-Alert keep a limited amount of data available. By default, Planefence keeps 90 days of data around, while Plane-Alert isn't time limited. This data is accessible using a REST interface that makes use of HTTP GET. You can access this API from the directory where your Planefence or Plane-Alert web pages are deployed. For example:
- If Planefence is available at https://planefence.com/planefence, then you can reach the Planefence API at https://planefence.com/planefence/pf_query.php
- If Plane-Alert is available at https://planefence.com/plane-alert, then you can reach the Plane-Alert API at https://planefence.com/plane-alert/pa_query.php
The Planefence and Plane-Alert APIs accept awk-style Regular Expressions as arguments. For example, a tail number starting with N, followed by 1 digit, followed by 1 or more digits or letters would be represented by this RegEx: n[0-9][0-9A-Z]* . Query arguments are case-insensitive: looking for n or for N yields the same results.
Each query must contain at least one of the parameters listed below. Optionally, the type parameter indicates the output type. Accepted values are json or csv; if omitted, json is the default value. (These argument values must be provided in lowercase.)
Note that the call parameter (see below) will start with @ followed by the call (tail number or flight number as reported via ADS-B/MLAT/UAT) if a notification was sent for the entry. So make sure to start your call query with ^@?.
| Parameter | Description | Example |
|---|---|---|
hex |
Hex ID to return | https://planeboston.com/planefence/pf_query.php?hex=^A[AB][A-F0-9]*&type=csv returns a CSV with any Planefence records of which the Hex IDs that start with A, followed by A or B, followed by 0 or more hexadecimal digits |
tail |
Call sign (flight number or tail) to return | https://planeboston.com/planefence/pf_query.php?call=^@?AAL[0-9]*&type=json returns any flights of which the call starts with "AAL" or "@AAL" followed by only numbers. (Note - the call value will start with @ if a notification for the entry was sent, in which case the tweet_url field contains a link to the notification (legacy field name - notification is probably NOT to X/Twitter!)) |
start |
Start time in secs_since_epoch |
https://planeboston.com/planefence/pf_query.php?start=163989.*&type=csv returns all entries that started on Dec 19, 2021. |
end |
End time, format secs_since_epoch |
https://planeboston.com/planefence/pf_query.php?end=163989.*&type=csv returns all entries that ended before Dec 19, 2021. |
| Parameter | Description | Example |
|---|---|---|
hex |
Hex ID to return | https://planeboston.com/plane-alert/pa_query.php?hex=^A[EF][A-F0-9]*&type=csv returns a CSV with any Planefence records of which the Hex IDs that start with A, followed by E or F, followed by 0 or more hexadecimal digits. (Note - this query returns most US military planes!) |
tail |
Tail number of the aircraft | https://planeboston.com/plane-alert/pa_query.php?tail=N14[0-9]NE&type=csv returns any records of which the tail starts with "N14", followed by 1 digit, followed by "NE". |
name |
Aircraft owner's name | https://planeboston.com/plane-alert/pa_query.php?name=%20Life|%20MedFlight&type=csv returns any records that have " Life" or " MedFlight" in the owner's name. |
equipment |
Equipment make and model | https://planeboston.com/plane-alert/pa_query.php?equipment=EuroCopter returns any records of which the equipment contains the word "EuroCopter" |
timestamp |
Time first seen, format yyyy/MM/dd hh:mm:ss |
https://planeboston.com/plane-alert/pa_query.php?timestamp=163989.* returns any records from Dec 19, 2021. |
call |
Callsign as reported by aircraft | https://planeboston.com/plane-alert/pa_query.php?call=SAM returns any records of which the callsign contains "SAM". |
lat |
Latitude first observation, in decimal degrees | https://planeboston.com/plane-alert/pa_query.php?lat=^43 returns any records of which the latitude starts with "43" (i.e., 43 deg N) |
lon |
Longitude first observation, in decimal degrees | https://planeboston.com/plane-alert/pa_query.php?lon=^-68 returns any records of which the longitude starts with "-68" (i.e., 68 deg W) |
- If your system doesn't behave as expected: check, check, double-check. Did you configure the correct container in
docker-compose.yml? Did you edit theplanefence.configfile? - Check the logs:
docker logs -f planefence. Some "complaining" about lost connections or files not found is normal, and will correct itself after a few minutes of operation. The logs will be quite explicit if it wants you to take action - Check the website: http://myip:8088 should update every 80 seconds (starting about 80 seconds after the initial startup). The top of the website shows a last-updated time and the number of messages received from the feeder station.
- Plane-alert will appear at http://myip:8088/plane-alert
- Error "We cannot reach {host} on port 30003". This could be caused by a few things:
-
Did you set the correct hostname or IP address in
PF_SOCK30003HOSTinplanefence.config? This can be:- The name of another container in the same Docker compose stack, e.g.,
ultrafeederortar1090 - IP address or an external hostname to a different server
- IP address or an external hostname to the same server if the Docker instance of
ultrafeeder,tar1090, etc. is in a different stack, e.g., adsb.im feeder image
- The name of another container in the same Docker compose stack, e.g.,
-
Did you enable SBS (BaseStation -- not Beast!) output? Here are some hints on how to enable this:
-
For non-containerized
dump1090[-fa]/readsb/tar1090: add command line option--net-sbs-port 30003 -
For containerized
readsb-protobuf: add to theenvironment:section of yourdocker-compose.ymlfile:- READSB_NET_SBS_OUTPUT_PORT=30003 - READSB_EXTRA_ARGS=--net-beast-reduce-interval 2 --net-sbs-reduce
-
For users of the
ultrafeedercontainer, no additional changes should be needed (see below for enabling MLAT aircraft)
-
-
If you are using multiple Docker container stacks, then you should also add
- 30003:30003to theports:section in thedocker-compose.ymlfile that contains yourultrafeeder,tar1090,readsb, or service. -
For users of
ultrafeeder, if you want to enabled MLAT, make sure to set the following parameter in theultrafeederenvironment variables:- READSB_FORWARD_MLAT_SBS=true
-
- If you need further support, please join the #planefence channel at the SDR Enthusiasts Discord Server and look for "@kx1t" to your message. Alternatively, email me at
kx1t {at} kx1t {dot} com.
That's all!
Planefence is licensed under the GNU GPL v3 License. Planefence's Data Use and Privacy policy is documented in the Privacy Policy.
