Wheeler Keeper: The Self-Hosted Vehicle Maintenance Tracker That Never Forgets
The Problem With Car Maintenance
You know the feeling. You’re at the petrol station and you notice the little sticker on the windscreen — but you can’t remember if that’s the old interval or the one the mechanic updated last visit. Your oil change was definitely around 15,000 km. Your brake pads were done… last winter? Or the winter before?
Car maintenance is one of those things that desperately needs a log but almost nobody keeps one. Receipts pile up in the glovebox, service books get lost, and memory fades. By the time something feels wrong, you’re already overdue.
Wheeler Keeper is a self-hosted Django web application that solves exactly this. It gives your vehicles a digital memory: every service logged with date, mileage, itemised costs, and a smart notification system that tells you when something is coming due — without you having to remember to check.
What You Can Track
Wheeler Keeper supports five vehicle types: cars, motorcycles, vans, motorhomes, and trucks. Each vehicle entry carries:
- Make, model, year, and plate
- Current odometer reading
- Full maintenance history
- Upcoming service predictions (by km and/or by months)
The maintenance type catalogue covers nine categories — engine, transmission, brakes, tyres, suspension, electrical, air conditioning, filters, and a catch-all — with default service intervals you can override per vehicle. That last detail matters: a turbocharged engine may need oil every 7,500 km while the manufacturer’s general recommendation says 15,000.
Logging a Service Session
When you visit the workshop, a single maintenance session can contain multiple items. You spent the afternoon at the garage: oil change, air filter, spark plugs. That’s one session with three ItemMantenimiento entries, each with:
- The maintenance category and type
- Description of the specific part used (e.g. Mann W712 oil filter, Castrol 5W30 4L)
- Quantity and unit cost
The session itself carries the workshop name, date, odometer at time of service, and a global labour cost. The cost model separates labour from parts, and supports toggling IVA (21% Spanish VAT) — either included in the prices you enter, or added on top at the totals stage.
| Field | Detail |
|---|---|
| Labour cost | Flat fee for the workshop’s time |
| Parts | Per-item: quantity × unit price |
| IVA toggle | 21% added to subtotal, or already included |
| Subtotal | Labour + all parts |
| Total | Subtotal ± IVA |
This gives you a clear breakdown of what you actually paid for the work versus the parts, which is useful when comparing workshops or budgeting future services.
Smart Notifications Without Cron Jobs
This is the part that makes Wheeler Keeper genuinely clever in its implementation.
Most maintenance reminder apps either require you to remember to open them, or they need an external cron job to fire at scheduled intervals — which in a self-hosted setup means configuring system-level cron, dealing with environment variables in shell context, and debugging silent failures.
Wheeler Keeper takes a different approach: a Django middleware (NotificacionesProgramadasMiddleware) that activates automatically on every incoming request. When a user navigates to any page, the middleware silently checks whether it’s already run a maintenance review for that user today. If not, it scans all vehicles for overdue or upcoming services and fires emails for anything that needs attention.
The notification logic covers two dimensions — time and mileage — and two urgency levels:
| Alert type | Trigger condition |
|---|---|
| 🚨 Overdue by time | Past the scheduled service date |
| 🚨 Overdue by mileage | Vehicle exceeded recommended km |
| 🔧 Upcoming by time | Service due within 30 days |
| 🔧 Upcoming by mileage | Within 1,000 km of next service |
An anti-spam guard ensures no user receives more than one notification per maintenance type per 24-hour window, tracked via the NotificacionMantenimiento model. Every sent notification is logged with timestamp, alert type, odometer reading, and delivery status.
The practical result: as long as at least one user opens the application occasionally, the notification system runs. No root access required, no cron configuration, no silent failures.
Multi-User System with Approval Workflow
Wheeler Keeper is designed for a small trusted group — family, flatmates, a small fleet manager — not open public registration. New users request access through a registration form, and an administrator approves or rejects each request from the Django admin panel.
The approval workflow supports both manual accounts (username + password) and Google OAuth (via django-allauth). When a Google-authenticated user requests access, the approval step creates both the Django user and the linked social account in one operation. Approved and rejected applicants each receive an email notification.
Deployment: Docker Compose in Two Commands
The entire stack — Django application, PostgreSQL database, and static files — is containerised and managed through Docker Compose. The Makefile wraps the common operations:
make first-time-setup # interactive guided setup
make install # build images, run migrations, load default data
make quick-start # daily start once already configured
make backup-db # manual PostgreSQL dump
Automated weekly backups run via a shell script (backup-cron.sh) that uses pg_dump, compresses the output, and rotates to keep the last 10 snapshots. An optional system cron entry triggers this on Sundays at 08:00.
The entrypoint.sh waits for PostgreSQL to accept connections before starting the Django process, avoiding the race condition that makes many Docker + database setups fail on first run.
Under the Hood
| Layer | Technology |
|---|---|
| Framework | Django |
| Database | PostgreSQL (via Docker volume) |
| Authentication | Django auth + django-allauth (Google OAuth) |
| SMTP (Gmail App Password or any SMTP server) | |
| Notifications | Django middleware — no external scheduler |
| Containerisation | Docker + Docker Compose |
| Static files | Django collectstatic → served from container |
| Backups | pg_dump + gzip, rotating 10 snapshots |
Try It
The live instance is available at wheeler-keeper.box2overtake.com. You can request access directly from the registration page.
To self-host your own instance, the repository contains everything you need — docker-compose.yml, configuration templates, and the full Makefile with commented targets for every operation.
Your car remembers every pothole. Wheeler Keeper remembers everything else.
Last modified: 21 Jun 2026