Track how many times your container images are pulled — with a ready-made Grafana dashboard
10K+
Track how many times your container images are pulled, with a ready-made Grafana dashboard.
When you publish a container image to Docker Hub or GitHub Container Registry (GHCR), each registry tracks how many times that image has been downloaded, but there's no built-in way to see those numbers over time, compare trends, or get alerts. Registry Stats solves this by polling the registries on a schedule and exposing the download counts as Prometheus metrics for dashboards and alerting.
/metrics): pull counts as gauges, scraped by any Prometheus-compatible collector for native Grafana dashboardsmyuser/myapp) and owner wildcards (myuser/*) to discover public repos on each poll. Docker Hub wildcards collect up to 198 repositories per owner: its unauthenticated API refuses offsets of 100 or more, so Registry Stats reads two pages of 99. GHCR wildcards read up to fifty listing pages, about 1,500 packages as GitHub currently paginates them; reaching that cap logs a truncation warning. Each poll logs the collected count, and the advertised total where the registry publishes one.httpx, health, metrics, webhttp, scheduler, slogx, envx, and runesafe libraries, which supply retry/backoff, the health probe, Prometheus exposition, the HTTP server lifecycle, the poll loop, UTC logging, environment parsing, and the bound on scraped text reaching the log stream. Small, auditable supply chain.nonroot on gcr.io/distroless/static-debian13 with no shell or package manager, minimising attack surface.docker pull cplieger/registry-stats:latest
Also published to ghcr.io/cplieger/registry-stats with identical images and tags. Release versions are tagged vX.Y.Z alongside latest.
# Example compose for registry-stats. See the README for all configuration options and hardening.
services:
registry-stats:
image: ghcr.io/cplieger/registry-stats:latest
container_name: registry-stats
restart: unless-stopped
environment:
# Set at least one repo; leaving both empty makes the container report unhealthy after the first collect.
DOCKERHUB_REPOS: "" # owner/repo or owner/* format, comma-separated
GHCR_REPOS: "" # owner/package or owner/* format, comma-separated
POLL_INTERVAL_HOURS: "1" # 0 = collect once then serve
ports:
# This endpoint has no authentication, so the example publishes it to this host only.
# For a collector on another host, publish on that trusted interface: "192.168.1.10:9100:9100", never "9100:9100".
- "127.0.0.1:9100:9100"
GPL-3.0-or-later. See LICENSE. The image carries the license text of every bundled component under /usr/share/licenses/.
Content type
Image
Digest
sha256:d8cf52268…
Size
4.1 MB
Last updated
about 14 hours ago
docker pull cplieger/registry-stats