# V3-17 — Self-hosted OSRM: investigate and stand one up **Phase** Infrastructure · **Depends on** nothing · **Size** M · **Blocks** V3-08, V3-09 · **Status** Not started ## Goal Get a self-hosted OSRM instance running somewhere, so V3-08 (road-snapped routing and ETA) has a real backend to build against instead of a deferred decision. ## Context V3-08 named the choice of routing engine as "a decision that cannot be deferred," and [the conversation that spawned this ticket](../v3/README.md) picked a direction without picking a provider: **self-hosted OSRM**, over a hosted API (GraphHopper, Mapbox Directions) or the public OSRM demo (explicitly not for production use). **This ticket exists because that decision itself has a wrinkle worth naming up front:** this whole v3 backlog's organizing principle, stated in `docs/BACKLOG.md`, is *"v3 is everything that can be built with no server. v4 is everything that cannot."* A self-hosted OSRM instance is a server. Strictly, that makes V3-08 and V3-09 — anything that depends on this ticket — v4 work by the project's own definition, not v3, even though they're filed under `docs/v3/` today and the routing itself has nothing to do with the group-rides/accounts/backup programme that currently defines v4. Whether to formally renumber them is a documentation decision for whoever picks this up next; this ticket does not resolve it, only flags it so it isn't silently glossed over. ## Design Two separable questions: 1. **Where does it run?** A small VPS (the same shape of box that would eventually host the v4 group-ride server, so this could double as an early step toward that) versus something serverless/managed. OSRM's own Docker image is the standard path either way. 2. **What data does it need?** A regional OSM extract, not the planet — start with whatever region actually gets ridden (per `docs/LAUNCH.md`, this is presently a friends-and-family app, so the region is small and known). [Geofabrik](https://download.geofabrik.de/) publishes regional `.osm.pbf` extracts sized for exactly this. Profiles matter for this app specifically (see V3-08's Design section): a motorcycle route and a bicycle route between the same two pins should genuinely differ. OSRM ships car/bike/foot profiles out of the box; a motorcycle profile is closer to car (mostly avoids the walk-only restrictions bike profiles impose) but might want the twisty-road preference a stock car profile doesn't have reason to express. Confirming that is part of this ticket's investigation, not something to guess at now. ## Implementation 1. Pick and provision a host (see Design's first question) 2. Download and preprocess a regional extract with OSRM's own toolchain (`osrm-extract` → `osrm-partition` → `osrm-customize`, or the older `osrm-contract` pipeline depending on the OSRM version chosen) 3. Run `osrm-routed` behind whatever the host offers for TLS termination — the app will be calling this over the public internet from riders' phones, so plain HTTP is not an option 4. Confirm at least a car-equivalent and a bike profile both return sane routes for a handful of real local pin pairs, by hand, before writing any app code against it 5. Write the resulting base URL and auth (if any) down for V3-08 to consume — as configuration, never a hardcoded value, matching V3-08's own "no API key committed to the repository" acceptance criterion, which applies here too even though there's no third-party vendor to protect a key from — an open, unauthenticated routing endpoint is still worth not publishing in a public repo 6. A basic uptime check of some kind — this becomes a real dependency the app relies on, not a fire-and-forget script ## Acceptance criteria - [ ] An OSRM instance is reachable over HTTPS from outside the host network - [ ] Returns a road-following route for a real pin pair in the region actually ridden - [ ] At least two distinct profiles (car-equivalent, bike) both work - [ ] The endpoint and any credentials live in configuration, not source - [ ] Documented: what's running, where, how to update the extract when it goes stale, and what it costs (if anything) to keep running ## Tests Infrastructure, not app code — no `flutter test` coverage belongs to this ticket directly. V3-08's own `FakeRoutingService`-driven tests are what verify the app's behavior; this ticket's job is only to make the real thing exist for that fake to stand in for. ## Risks - **Ongoing hosting cost and maintenance**, however small — this is the first piece of always-on infrastructure this project has taken on. Worth being honest that "no server" stopped being true the moment this ticket is picked up, regardless of which numbering bucket it ends up filed under. - **OSM extracts go stale.** A road that didn't exist at extract time won't route. Needs a refresh cadence, not a one-time setup. - Regional extracts are cheap; do not reach for a planet-wide extract preemptively. ## Out of scope Actually building V3-08/V3-09 against this once it exists — that's their ticket, not this one. Turn-by-turn navigation, traffic-aware routing, anything beyond what stock OSRM gives you.