this post was submitted on 25 Sep 2026
94 points (98.0% liked)

Selfhosted

62310 readers
696 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

Rules:

Detailed Rules Post

  1. Be civil.

  2. No spam.

  3. Posts are to be related to self-hosting.

  4. Don't duplicate the full text of your blog or readme if you're providing a link.

  5. Submission headline should match the article title.

  6. No trolling.

  7. Promotion posts require active participation, with an account that is at least 30 days old. F/LOSS without a paywall has exceptions, with requirements. See the rules link for details. Tags [CBH] or [AIP] are required, see the links in Rule 8 for details.

  8. AI-related discussions and AI-involved promotional posts have additional requirements for tagging, as noted in Rule 7 and the AI & Promotional Post Expanded Rules post, and find example disclosures here.

Resources:

Any issues on the community? Report it using the report flag.

Questions? DM the mods!

founded 3 years ago
MODERATORS
 

TL;DR of the TL;DR: Private, self hosted, GPS enabled, local search and offline routing map engine in under a gigabyte, on a $55 SBC, accessible anywhere.

Ok...I've been working on this for a while and it is SO satisfying to see it to completion.

I'm calling it "Pi maps" (because the Pi hosts it) but it's really MapLibre GL JS, served locally by nginx. The Western Australia basemap is a single PMTiles archive, clipped from the Protomaps daily build to the WA boundary, zoom levels 0-15. The finished stack is about 770 MB.

770MB!

PMTiles is one of the bits I particularly like. Instead of running a tile server and maintaining millions of little tile files or a tile database, nginx just serves one archive with HTTP Range requests. Then MapLibre asks for the byte ranges it needs.

The map-serving path is:

Browser
  ↓
MapLibre GL JS
  ↓
PMTiles JS
  ↓
nginx HTTP Range requests
  ↓
WA.pmtiles

And the best part is that I needed no PostgreSQL, PostGIS or live calls to Google etc.

But wait...there's more! Search and routing!

Rather than install something heavy, I put together a small search service using Python, from the OSM extract.

The source data is converted into a SQLite FTS5 database and the current index contains about 300,000 source records, for a whopping...78 MB. The runtime search service uses about 11 MB RAM at idle.

Driving routes are calculated locally using BRouter, which runs as its own container and nginx proxies the route API internally to it.

The routing dataset for turned out to be remarkably small - roughly 20 MB, with a single worker and a 128 MB Java heap.

The browser gets route geometry, distance, ETA and turn instructions without calling an external routing service.

TL;DR: The current stack is basically three containers:

  • pi-maps - nginx + the MapLibre frontend + PMTiles
  • pi-maps-search - Python + SQLite FTS5 local search
  • pi-maps-brouter - local driving-route engine

After testing, the individual Maps components were around:

nginx/frontend       ~7.3 MiB
search service       ~11.2 MiB
BRouter              ~168 MiB
--------------------------------
total                ~187 MiB RAM

The complete thing - map, search database, routing data, local web assets, metadata etc ends up at roughly 770 MB.

So - a Raspberry Pi 4 is locally serving a zoomable map, POI/address search and actual driving routes for comfortably under a gigabyte of application data.

What's more, I can use it remotely via Tailscale if I want and/or download the tiles directly to my phone and use it with something like GeoLibre or Atlas.

OSM / Protomaps data
        ↓
   Raspberry Pi
        ↓
 ┌───────────────┐
 │ WA.pmtiles    │ → map
 │ SQLite FTS5   │ → search
 │ BRouter       │ → directions
 └───────────────┘
        ↓
 Browser / phone / apps

It's not yet a Google Maps replacement. Yet. Right now the routing profile is driving-focused; there is no live turn-by-turn rerouting, spoken navigation, traffic data, or giant commercial address database. But...I have ideas and too much free time (actually, I think I can solve the 4 of those 5 pretty simply).

Case in point: there was a cool technical problem in that the the POI polygon centroid can be a valid map location but NOT a valid driving destination. That was fun to solve.

The next thing I'm going to try is adding a wikipedia layer - or rather, a self hosted ZIM wikipedia layer - so that POIs actually resolve to clickable entries.

There. For once, I win.

PS: This was much easier to do that the whole "family chat" bullshit. Never work with children or animals.

PPS: Also, I may have broken the family chat IRC server, or at least, misunderstood how IRC uses connection resets. So..XMPP might win after all, much to my chagrin.

you are viewing a single comment's thread
view the rest of the comments
[–] eleijeep@piefed.social 15 points 18 hours ago (1 children)

Are you planning on sharing the source?

[–] SuspiciousCarrot78@aussie.zone 22 points 18 hours ago* (last edited 18 hours ago) (4 children)

I mean...if there's interest? Just let me figure out those last four nagging pains in the ass and I will put it up. The thing itself is pretty simple lego: frontend, nginx config, SQLite/FTS search service, index-builder scripts, BRouter integration, route-anchor logic.

Right now, I have a few irons in the fire, including a fork called SmartTube Local that is turning into a passion project.

That one is basically: “what if YouTube was local-first, self-hosted and yt-dlp-backed, with the local archive integrated directly into the app and automatically kept up to date...so if the internet died, your kids might not even notice?”

...I just did google maps...why not take on Youtube next, amirite?

[–] Cyber@feddit.uk 1 points 2 hours ago (1 children)

If you release your code, others might be able to help you get those last parts done, perhaps even optimise it.

For me, that's the hardest part... letting others contribute to my projects 🙂

Oh, I will release...but no PRs / maintenance debt is better for me.

Feel free to fork and tinker with it - and I hope you do - but this is a personal project you all convinced me to share :)

Seeing people are keen on this, I will get LLM to write up documentation real quick (GASP!) and then push it to github. Gimme an hour

[–] hendrik@palaver.p3x.de 13 points 16 hours ago* (last edited 16 hours ago)

There's always interest in sources. Otherwise you'd be the only one able to self-host the software. 😉

[–] eleijeep@piefed.social 11 points 18 hours ago

Yeah I mean to you it might be pretty simple lego :) but I'm sure lots of people would benefit from it. Even if not to use the same exact setup then to provide an example or starting point for DIY.

[–] hirihit640@sh.itjust.works 2 points 16 hours ago* (last edited 16 hours ago) (1 children)

Have you heard of Tube Archivist?

Edit: ok i see you mentioned it in your Local Smarttube announcement post. Why doesn't Tube Archivist fit your needs?

[–] SuspiciousCarrot78@aussie.zone 5 points 16 hours ago* (last edited 15 hours ago)

TubeArchivist is:

  1. heavy (Redis, Elasticsearch).
  2. doesn't have a native TV app.
  3. will not play nicely with the Raspberry Pi (table stakes are 2 GB RAM, which is more than half my RAM budget).

I like TA a lot, but not for what I have in mind. What I have in mind should use about 100 MB of RAM, run as a systemd service, with videos served directly to the front-end via Samba, in such a manner that they are indistinguishable from the cloud sources when displayed in-app (well, apart from a core badge saying LOCAL).

I'm not coding a simple Jellyfin plug in.