graphs1090
graphs1090 — performance graphs for readsb / dump1090-fa ADS-B receivers, hub-built
10K+
Unofficial community image for graphs1090, built with LinuxServer.io style container patterns (s6, hardened defaults, practical runtime options) for ADS-B performance graphing workloads. Sponsored and maintained by Blackout Secure.
Important
This repository is not an official LinuxServer.io image release. Want to help make it an officially supported LinuxServer.io Community image? Add your support in [linuxserver/discussions/112](https://github.com/orgs/linuxserver/discussions/112).
Links: Docker Hub · Balena block · GitHub · Upstream graphs1090
docker run -d \
--name=graphs1090 \
--restart unless-stopped \
-e TZ=Etc/UTC \
-e GRAPHS1090_DECODER_DIR=/run/readsb \
-p 8080:8080 \
-v graphs1090-config:/config \
-v collectd-rrd:/var/lib/collectd/rrd \
-v /path/to/readsb/json:/run/readsb:ro \
blackoutsecure/graphs1090:latest
Access the web UI at http://<host-ip>:8080/graphs1090/.
For compose files, balena, and more examples, see Usage below.
Docker Hub (Recommended):
docker pull blackoutsecure/graphs1090:latest# Pull latest
docker pull blackoutsecure/graphs1090
# Pull specific version
docker pull blackoutsecure/graphs1090:1.0.1
# Pull architecture-specific (rarely needed)
docker pull blackoutsecure/graphs1090:latest@amd64
graphs1090 generates performance graphs for readsb / dump1090-fa ADS-B receivers, providing visual insight into signal strength, message rate, aircraft count, range, CPU, and other metrics over time.
Author and maintenance credits (upstream):
This image is published as a multi-arch manifest. Pulling blackoutsecure/graphs1090: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:
graphs1090:
image: blackoutsecure/graphs1090:latest
container_name: graphs1090
environment:
- TZ=Etc/UTC
- GRAPHS1090_DECODER_DIR=/run/readsb
volumes:
- config:/config
- collectd-rrd:/var/lib/collectd/rrd
- /path/to/readsb/json:/run/readsb:ro
ports:
- 8080:8080 # Web UI (HTTP)
cap_drop:
- ALL
cap_add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- SETUID
- SETGID
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp
- /run:exec
restart: unless-stopped
volumes:
config:
collectd-rrd:
---
services:
readsb:
image: blackoutsecure/readsb:latest
container_name: readsb
environment:
- TZ=Etc/UTC
volumes:
- readsb-config:/config
- readsb-run:/run/readsb
devices:
- /dev/bus/usb:/dev/bus/usb
tmpfs:
- /tmp
- /run:exec
restart: unless-stopped
graphs1090:
image: blackoutsecure/graphs1090:latest
container_name: graphs1090
environment:
- TZ=Etc/UTC
- GRAPHS1090_DECODER_DIR=/run/readsb
volumes:
- graphs1090-config:/config
- collectd-rrd:/var/lib/collectd/rrd
- readsb-run:/run/readsb:ro
ports:
- 8080:8080
depends_on:
- readsb
cap_drop:
- ALL
cap_add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- SETUID
- SETGID
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp
- /run:exec
restart: unless-stopped
volumes:
readsb-config:
readsb-run:
graphs1090-config:
collectd-rrd:
docker run -d \
--name=graphs1090 \
-e TZ=Etc/UTC \
-e GRAPHS1090_DECODER_DIR=/run/readsb \
-p 8080:8080 \
-v /path/to/graphs1090/config:/config \
-v /path/to/collectd/rrd:/var/lib/collectd/rrd \
-v /path/to/readsb/json:/run/readsb:ro \
--restart unless-stopped \
blackoutsecure/graphs1090: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 | Function |
|---|---|
-p 8080:8080 | Web UI (HTTP) |
| Parameter | Function | Required |
|---|---|---|
-e TZ=Etc/UTC | Timezone (TZ database) | Optional |
-e GRAPHS1090_DECODER_DIR=/run/readsb | Path to decoder JSON directory (stats.json, aircraft.json) | Optional |
-e GRAPHS1090_UAT_DIR= | Path to 978 MHz UAT decoder directory (enables UAT graphs) | Optional |
-e GRAPHS1090_PORT=8080 | HTTP port for the web UI | Optional |
-e GRAPHS1090_USER=abc | Runtime user | Optional |
-e PUID=911 | User ID for file ownership | Optional |
-e PGID=911 | Group ID for file ownership | Optional |
| Parameter | Function | Required |
|---|---|---|
-v /config | Persistent configuration | Recommended |
-v /var/lib/collectd/rrd | RRD database storage — preserves graph history across restarts | Recommended |
-v /run/readsb | Decoder JSON input directory (mount read-only) | Required |
The container uses three volumes:
/config — Configuration & Persistence-v /path/to/graphs1090/config:/config or -v graphs1090-config:/config/var/lib/collectd/rrd — RRD Database Storage-v /path/to/collectd/rrd:/var/lib/collectd/rrd or -v collectd-rrd:/var/lib/collectd/rrd/run/readsb — Decoder JSON Inputstats.json, aircraft.json-v /path/to/readsb/json:/run/readsb:roEnvironment variables are set using -e flags in docker run or the environment: section in docker-compose.
The graphs1090 config file is /etc/default/graphs1090 inside the container. To customize, either mount a file into the container or edit it via docker exec.
| Variable | Default | Description |
|---|---|---|
colorscheme | default | Color scheme: default or dark |
range | nautical | Range unit: nautical, statute, or metric |
fahrenheit | 0 | Set to 1 for Fahrenheit |
graph_size | default | Graph size: small, default, large, huge, custom |
WWW_TITLE | graphs1090 | Browser tab title |
WWW_HEADER | Performance Graphs | Page heading |
DRAW_INTERVAL | 60 | Graph redraw interval in seconds |
HIDE_SYSTEM | no | Set yes to hide system resource graphs |
disk | (blank) | Block device for disk I/O graphs (e.g. mmcblk0) |
ether | (blank) | Network interface for wired stats (e.g. eth0) |
enable_scatter | no | Enable scatter plot data collection |
All options: upstream default config
volumes:
- ./my-graphs1090-config:/etc/default/graphs1090:ro
By default, this container runs as the LSIO abc user (non-root) for better security isolation. The abc user is created by the LinuxServer.io base image with UID/GID 911 and remapped at container start via PUID/PGID.
abc user — no root privileges required for normal operation.PUID and PGID only if you need file ownership on /config and /var/lib/collectd/rrd to match a specific host user./run/readsb) is read-only — graphs1090 never writes to your decoder's output.The container runs three services under s6-overlay:
During normal operation, collectd writes to /run/collectd (memory-backed tmpfs) to minimize disk I/O.
On container start, RRD data is restored from /var/lib/collectd/rrd/localhost.tar.gz to memory, with a fallback cascade: primary tarball, raw folder, this week's auto-backup, last week's auto-backup, or fresh start.
On container stop, RRD data is compressed and written back to disk. A weekly rotating backup is kept automatically with 60-day retention.
Verify the decoder JSON directory is mounted and populated:
docker exec graphs1090 ls -la /run/readsb/
docker exec graphs1090 head -c 200 /run/readsb/stats.json
If stats.json is missing, the decoder container is not providing data. Check that:
Initial data collection takes up to 10 minutes. Graphs with longer timespans (7-day, 30-day) will fill in gradually.
Map to a different host port:
docker run ... -p 8081:8080 ...
docker logs graphs1090
docker logs graphs1090 --tail 100 -f
docker exec graphs1090 s6-svstat /run/service/svc-collectd
docker exec graphs1090 s6-svstat /run/service/svc-graphs1090
docker exec graphs1090 s6-svstat /run/service/svc-nginx
docker logs -f graphs1090The container includes built-in health monitoring at multiple levels:
The image includes a HEALTHCHECK that performs an HTTP GET against the nginx web UI (http://127.0.0.1:${GRAPHS1090_PORT:-8080}/graphs1090/). Docker marks the container as unhealthy after 3 consecutive failures.
| Setting | Value |
|---|---|
| Interval | 30s |
| Timeout | 5s |
| Start period | 30s |
| Retries | 3 |
# Check container health status
docker inspect --format='{{.State.Health.Status}}' graphs1090
# View health check history
docker inspect --format='{{json .State.Health}}' graphs1090 | jq .
All long-running services are supervised by s6-overlay and automatically restarted on crash:
# Check individual service status
docker exec graphs1090 s6-svstat /run/service/svc-collectd
docker exec graphs1090 s6-svstat /run/service/svc-graphs1090
docker exec graphs1090 s6-svstat /run/service/svc-nginx
# Container health
docker inspect --format='{{.State.Health.Status}}' graphs1090
# Confirm decoder JSON input is reaching the container
docker exec graphs1090 ls -la /run/readsb/
docker exec graphs1090 head -c 200 /run/readsb/stats.json
# Web UI reachability from inside the container
docker exec graphs1090 wget -qO- http://127.0.0.1:8080/graphs1090/ | head -n 5
# Service uptime (all services)
docker exec graphs1090 s6-svstat /run/service/svc-collectd
docker exec graphs1090 s6-svstat /run/service/svc-graphs1090
docker exec graphs1090 s6-svstat /run/service/svc-nginx
This project uses semantic versioning:
latest, and architecture-specificUpdate to latest:
docker pull blackoutsecure/graphs1090:latest
docker-compose up -d # if using compose
Check image version:
docker inspect -f '{{ index .Config.Labels "build_version" }}' blackoutsecure/graphs1090:latest
MIT — see LICENSE. The upstream graphs1090 project is also MIT licensed.
Sponsored and maintained by Blackout Secure.
Content type
Image
Digest
sha256:309d9f563…
Size
34.8 MB
Last updated
about 2 months ago
docker pull blackoutsecure/graphs1090:sha-d1dd682a04119a798187c16976a52605a01cc6cc