Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

selfhosted-pulse

The two signals people use to pick self-hosted software disagree violently, and nobody is recording the one that would settle it.

app GitHub stars rank Docker pulls rank
Immich 112,360 1 32.5M 12
Heimdall 9,305 17 587M 3
Nextcloud 36,535 8 1.02B 1

Heimdall has one twelfth of Immich's stars and eighteen times its pulls. At least one of those numbers is badly wrong about adoption.

This repo records both, daily, so that in a month there is a third number: rate of change.

Why both public signals are broken

Stars are cumulative and never decay. They measure interest at first sight, not use. A project starred in 2019 and abandoned outranks one thriving today.

Docker pulls are cumulative too, so they reward age — and they are inflated by auto-updaters, CI and mirrors. One Watchtower user generates roughly 365 pulls a year, which is most of why linuxserver.io images dominate the raw ranking.

Rate of change survives both problems. Differencing removes the age bias, and the auto-updater inflation is a roughly constant multiplier per project, so a rising or falling daily delta still means adoption is rising or falling.

Docker Hub publishes no time series. The only way to have one is to start recording, which is why this exists and why the dataset is append-only.

What it does

python collect.py                # one row per app per day -> data/snapshots.csv
python collect.py --limit 30     # smoke test, exercises the pull path
python resolve.py                # extend the image map (slow, see below)

apps.json ships with 27 hand-verified image mappings so the collector runs on clone. Without a GITHUB_TOKEN the star lookups are capped at 60/hour, so a full local pass is not possible — the workflow supplies one.

Apps come from awesome-selfhosted-data — ~1350 projects with name, repo, stars, tags, and twelve months of commit history. It carries no container reference, so images are guessed from the repo name and confirmed against Docker Hub.

.github/workflows/daily.yml runs the collector on GitHub's infrastructure at 04:17 UTC. A missed day is a hole that cannot be backfilled from anywhere.

Honest limitations

Resolution is partial. A hand sample matched ~45% of Docker-tagged apps. Known misses — Home Assistant, Grist, Tandoor — do have images under names the heuristic does not generate. Improving this is the highest-value contribution.

Docker Hub throttles hard. Twelve concurrent workers had every request 429'd within seconds. resolve.py is deliberately serial with a 1.5s pause, so a full first pass takes hours. Run it in CI, not on a laptop.

A throttled request is never recorded as a negative. hub_exists returns three values — exists, definitively absent, could-not-tell — and apps are marked unknown rather than not_found when the answer was throttled. This matters because the first version of this script caught every exception and returned False: when Hub started answering 429 to everything, it wrote 721 false negatives and reported 3% coverage against 45% in the hand sample. If more apps come back unknown than resolved, the script says so loudly.

Pulls are not installs and this repo does not claim otherwise. What is being measured is image-fetch churn. The number people actually want — how many still run this after 30 days — is not derivable from any public source, and any directory claiming "real installs" without an install path is showing you click-throughs.

License

MIT. App metadata derives from awesome-selfhosted-data (CC-BY-SA / MIT — check that repo before redistributing apps.json).

About

The two signals people use to pick self-hosted software disagree violently. Daily snapshots of GitHub stars and Docker pull counts for ~1350 apps, so rate-of-change exists as a third signal. Append-only; Docker Hub publishes no time series.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages