OpenWrt/Docker dashboard for Strava rides, stats, maps, bike maintenance.
1.6K
A router-native activity stats and bike service tracker for OpenWrt. A single POSIX shell script driven by cron uses curl and jq to fetch activity data, then writes static HTML and JSON into uhttpd's web root — no extra daemon, almost no RAM. Three data sources are supported; the router's built-in web server serves everything. Can also run locally via Docker or Windows WSL.
| Source | Config file | When to use |
|---|---|---|
| Strava API (OAuth) | /etc/strava-my-activities.conf | You have a Strava API subscription. See Data-Source-Strava-API |
| Strava scrape mode | /etc/strava-my-activities.conf (STRAVA_MY_SOURCE=scrape) | No subscription — uses the browser session cookie. See Data-Source-Scrape-Mode |
| HealthSync / Google Drive | /etc/healthsync-activities.conf | Fully Strava-API-free — healthsync.app exports to Drive. See Data-Source-HealthSync |
| Page | URL | What it shows |
|---|---|---|
| Club leaderboard | /strava/ | Monthly/yearly distance ranking for your Strava club, filterable by year and month |
| My Activities | /strava/me/ | Sortable activity table with year/month/sport filters, bests strip, and monthly bar charts |
| Activity detail | /strava/me/activity.html | Stat cards, interactive route map (Leaflet + OSM), per-km splits, elevation, HR, cadence charts |
| Personal stats | /strava/me/stats.html | Aggregate KPIs, year-over-year heatmap, personal records, sport breakdown, day-of-week chart |
| Activity heatmap | /strava/me/heatmap.html | Full-viewport Leaflet heat overlay of all GPS routes; period + sport-type filter, city label overlay |
| Bike service | /strava/me/bike.html | Maintenance log per bike: parts, service types with km/hour/calendar thresholds, auto-mileage, cost tracking |
My Activities dashboard
Activity detail
Club leaderboard
STRAVA_CLUB_IDS), ranked by distance with avg speedPersonal stats
Activity heatmap
Bike service tracker
activities.json rides; gear mapping per bike; calendar picker for any dateSTRAVA_MY_CURRENCY in the config (default PLN)STRAVA_MY_BIKE_EMAIL in the config to activate sending; warning at ≥ 90%, alert at ≥ 100% of any threshold; each tier fires once, alert re-sends weekly while overdueData management
/activities/{id}) gradually over nightly runsSTRAVA_MY_BIKE_EMAIL on Strava layout changes, cookie expiry, or data-normalization failures (rate-limited to once/day)Section reordering (desktop only)
localStorage and restored on the next visitDark mode
prefers-color-scheme setting; manual choice is remembered in localStorage across sessionsCron self-healing (via strava-cron-guard)
STRAVA_NET_CHECK_WAIT seconds (default 2 min) for the WAN to come back, then aborts cleanly — no false-positive alerts during a brief reconnectSTRAVA_CRON_RETRIES times (default 2) with STRAVA_CRON_RETRY_DELAY seconds (default 5 min) between attempts; alert email is only sent after all retries are exhausted, and the subject line reports the total attempt countFull feature details: Features
| Club dashboard | My Activities dashboard |
|---|---|
![]() | ![]() |
| Personal stats | Activity detail (map + splits) | Bike service tracker |
|---|---|---|
![]() | ![]() | ![]() |
| Activity heatmap |
|---|
![]() |
| My Activities (dark) | Personal stats (dark) |
|---|---|
![]() | ![]() |
| Activity detail (dark) | Bike service (dark) |
|---|---|
![]() | ![]() |
| Club leaderboard (dark) |
|---|
![]() |
Screenshots generated from sample data via
node test/take-screenshots.mjs(orpowershell -File test/make-screenshots.ps1on Windows).
1. Install on the router (run from the repo root on your PC):
scp -r . [email protected]:/tmp/strava
ssh [email protected] sh /tmp/strava/install.sh
2. Edit the config (choose one data source):
vi /etc/strava-my-activities.conf # Strava API or scrape mode
# — or —
vi /etc/healthsync-activities.conf # HealthSync / Google Drive
3. Run once to verify:
strava-my-activities # (or: healthsync-activities)
strava-leaderboard
A healthy run ends with done.. Any ERROR: line means the run aborted — check credentials.
4. Browse:
http://<router-ip>/strava/me/http://<router-ip>/strava/5. Cron is already installed (23:50 leaderboard, 23:55 my-activities, Warsaw time). Check with crontab -l.
For full install options, path variables, and post-install verification see Installation.
The easiest way to run StatsServiceBook on any machine (Linux, Mac, Windows, Raspberry Pi):
# 1. Copy and fill in config template(s):
cp docker/strava-my-activities.conf.example my-activities.conf
# edit my-activities.conf — add CLIENT_ID / CLIENT_SECRET / REFRESH_TOKEN
# Optional: club leaderboard
cp docker/strava-leaderboard.conf.example leaderboard.conf
# edit leaderboard.conf — add CLIENT_ID / CLIENT_SECRET / REFRESH_TOKEN / CLUB_IDS
# Optional: HealthSync / Google Drive (Strava-API-free)
# cp docker/healthsync-activities.conf.example healthsync.conf
# 2. Start:
docker compose up -d
# 3. Open http://localhost/strava/me/
Or without compose:
docker run -d --name statsservicebook \
-p 80:80 \
-v "$(pwd)/my-activities.conf:/etc/strava-my-activities.conf:ro" \
-v statsservicebook_data:/data \
-e TZ=Europe/Warsaw \
-e RUN_ON_START=1 \
jraczek/statsservicebook:latest
Supported architectures: amd64, arm64, arm/v7 (Raspberry Pi).
Full setup, config options, and docker-compose reference: Docker.
Quick preview with sample data — no credentials needed:
podman build -f test/Containerfile -t stravame-test .
podman run --rm -p 8080:8080 stravame-test
# Open http://localhost:8080/strava/me/
Run functional tests:
powershell -ExecutionPolicy Bypass -File .\test\run-tests.ps1
Full instructions for running with real credentials, HealthSync, or Windows WSL: Running-Locally.
rootcurl, jq, ca-bundle (~1–2 MB); use extroot on tight 128 MB flashpwsh) for running the test suite locally| Wiki page | Contents |
|---|---|
| Home | Index of all wiki pages |
| Features | Detailed description of every feature across all five pages |
| Installation | Full install guide, path variables, scheduling, verification |
| Data-Source-Strava-API | Create Strava app, one-time OAuth, token handling |
| Data-Source-Scrape-Mode | My Activities scrape mode, Club leaderboard scrape mode, session cookie |
| Data-Source-HealthSync | Google Drive OAuth, HealthSync setup, Magene FIT, dual-source detection |
| Docker | Docker Hub quick start, config templates, docker-compose, publishing |
| Running-Locally | Docker preview, real-data Docker, WSL, HealthSync local test |
| Email-Notifications | Bike service alerts, monthly/weekly/yearly leaderboard email, cron error alerts, Gmail App Password |
| Upgrading | Binary-only scp deploy, full reinstall, surviving sysupgrade |
| Switching-Data-Sources | API → scrape mode, Strava → HealthSync migration steps |
| Operations | Full file/URL reference, limitations, rate limits |
Content type
Image
Digest
sha256:7cc1c495d…
Size
12.2 MB
Last updated
5 days ago
docker pull jraczek/statsservicebook