EcoCommute SA
A free commuter app for South Australia, shipped on iOS and Android. Backed by a self-hosted OSRM + Nominatim + TileServer GL stack on the home cluster.
- Platforms
- iOS · Android
- Price
- Free
- Backend
- Self-hosted
- Failover
- ~60 s
The app
Screens
A few of the in-app surfaces. Same app on both platforms, backed by the same self-hosted mapping stack.




The mapping backend
A Docker-in-LXC container running OSRM for car/bike/foot routing, Nominatim for geocoding, TileServer GL for vector and raster tiles, and Portainer for managing the three. The mobile clients hit these services directly instead of paying a third party per-request, which means routing and search costs scale with electricity rather than user count.
Request flow
browser
│
▼ https://osrm.tech2urdoor.org/route/v1/driving/...
Cloudflare edge
│
▼ via cloudflared tunnel in haos VM 104
HA cloudflared add-on ──► ingress map
│
▼ http://192.168.1.130:5000 (MAC-pinned, IP follows the CT)
CT 118 (pvewyse5070)
│
▼ docker compose network
├─► osrm-backend :5000
├─► nominatim :8080
├─► tileserver-gl :8081
└─► portainer :9000 (LAN-only)HA-managed with replication
The container is in the Proxmox HA group with a ZFS replication job pushing snapshots to pvehp every 15 minutes. If the primary host needs a reboot, a single command brings the container up on the standby with about a minute of downtime, and the LAN IP follows it via a MAC-pinned reservation in the gateway:
# planned migration: fast because pvehp has a recent snapshot
$ sudo ha-manager migrate ct:118 pvehp
Requesting HA migration for VM 118 to node pvehp
# replicated incrementally; only the delta since the last 15-min snapshot moves
$ sudo pvesr status | grep 118-0
118-0 Local/pvewyse5070 -> pvehp 2026-05-22 21:45:01 OK 64.7sOperational notes
Nominatim’s import is the bulky part: a planet-scale Postgres database that wants a lot of RAM during initial load. OSRM is the opposite: contractions are built ahead of time and the runtime is essentially read-only with tiny memory pressure.
The whole stack treats the LXC rootfs as ephemeral. The interesting state (the OSRM graphs, the Nominatim database, the tile cache) all lives on the ZFS dataset that gets replicated, so the recovery plan after total host loss is to restore the dataset and start the containers.
