Jake 2d63006bdc Rebrand to volundr; add deploy artifacts
- User-facing brand "bike-admin" -> "volundr" (page titles, top bar,
  login header, FastAPI title, README/AGENTS). Directory, remote,
  BIKE_ADMIN_* env prefix and bike_admin.db filename are unchanged.
- Add deploy/: systemd unit (bike-admin.service) and a production
  .env template (env.production.example).
2026-09-10 11:29:49 +01:00
2026-09-09 17:49:01 +01:00
2026-09-09 17:49:01 +01:00
2026-09-09 17:49:01 +01:00
2026-09-09 17:49:01 +01:00
2026-09-09 17:49:01 +01:00

volundr

A small, secure, single-user web app for logging bike service and repair "events" (type, date, mileage, cost, notes) and getting a clear service-due hint per bike, plus MOT / insurance renewal tracking.

Built with FastAPI + SQLite + Jinja2 + HTMX. No build step. Server-rendered pages.

Features

  • Log events for a bike: type (service, fuel, tyre, chain, brake, repair, mot, insurance, other), date, optional mileage + cost, free-text notes.
  • Per-bike service status derived from your newest mileage and the most recent service event: ok (still under the interval), due-soon (within the lead time — book it soon), or overdue (past it — book a service now).
  • MOT / insurance renewals: the most recent mot / insurance event is tracked and flagged ok / due-soon / overdue by date (default: valid for 12 months, "due soon" within the final 60).
  • Set a service interval in miles per bike (e.g. 5000).
  • Dashboard "action needed" strip surfaces any overdue bike.
  • Cost and event totals, newest-first history.
  • Secure login (Argon2id hashing, server-side session, CSRF, login throttling, hardened security headers, strict CSP). Designed to run behind a reverse proxy on the open web.

Quick start

# 1. Install dependencies
uv sync --all-extras

# 2. Configure credentials (required)
export BIKE_ADMIN_USERNAME=admin
export BIKE_ADMIN_PASSWORD=<change-me>
export BIKE_ADMIN_SECRET_KEY=$(python -c "import secrets;print(secrets.token_urlsafe(32))")

# 3. Run
uv run uvicorn app.main:app --host 127.0.0.1 --port 8000
# open http://127.0.0.1:8000

Or copy .env.example to .env and fill in the values (env vars and the local .env file are both read automatically).

Tests / lint

uv run pytest -q
uv run ruff check app tests
uv run ruff format --check app tests

Running behind a reverse proxy (production)

  • Terminate TLS at the proxy (nginx/apache/caddy) and forward to the app.
  • Set BIKE_ADMIN_IS_PRODUCTION=true so the session cookie is Secure.
  • Bind to the private address: uvicorn app.main:app --host 127.0.0.1 --port 8000
  • Pass X-Forwarded-For / X-Forwarded-Proto so throttling + secure-cookie logic see the real client IP/protocol (the app trusts these by default).

Back up your data by copying the single file data/bike_admin.db (SQLite, WAL).

S
Description
basic small personal website for keeping track of my motorbike meintenance and admin
Readme
214 KiB
Languages
Python 71.2%
HTML 16.6%
CSS 12.2%