Skip to content

Self Hosting

Lwb89dev edited this page Oct 19, 2026 · 1 revision

Self-hosting

Roadstr talks to public services by default, but two of them can be replaced by your own, and a third is planned. Self-hosting keeps your requests off third-party servers.

Routing: GraphHopper

Run your own GraphHopper server and choose it in Settings → Map → Routing provider → GraphHopper (local/private). Enter the server address (for example http://localhost:8989/route) and use Verify to check it. No API key is needed for your own server. Car, cycling and walking profiles are supported.

You can also route with no server at all by installing an offline routing package — see Maps and offline use.

Web results: SearXNG

Web results are off until you type the address of an instance. Roadstr has no built-in instance and no list of fallbacks. This section says what the app needs from yours; the full guide, with a minimal Docker setup, is docs/world-discovery/SELF_HOSTING.md.

What the app needs

  • The address. https works for any address. Plain http works for the device itself (localhost, 127.0.0.1) and, once you tick “this is my own instance”, for local networks (private IPv4 ranges, 100.64.0.0/10 used by some VPNs, and names ending .local, .lan, .home.arpa, .internal or without a dot). No user:password@, no ?query or #fragment.
  • No redirects. Roadstr does not follow them, so the address must answer directly (no http→https or www redirect).
  • The answers. GET /config (the engine list) and GET /search?q=…&format=json&engines=…&language=…&safesearch=…&pageno=1. JSON must be enabled, and an answer must arrive within 8 seconds and fit in 1 MiB.
  • Nothing in front that wants a browser — a JavaScript check, captcha or “checking your browser” page cannot be solved by the app.

Minimal settings.yml

use_default_settings:
  engines:
    remove:
      - google
      - startpage

server:
  secret_key: "put a long random string here"   # e.g. openssl rand -hex 32
  limiter: false
  public_instance: false
  image_proxy: false

search:
  formats:
    - html
    - json
  safe_search: 1

search.formats must list json; change secret_key; limiter: false is right for a private instance — if it is reachable from the internet, protect it at the network level (a VPN or allow-list), not with a bot check. Then:

docker run --name searxng -d -p 8888:8080 \
    -v "./config/:/etc/searxng/" -v "./data/:/var/cache/searxng/" \
    docker.io/searxng/searxng:latest

Reaching it from the phone

  • Same network: http://192.168.x.y:8888, with “this is my own instance” ticked.
  • Away from home: put the phone and server on a WireGuard tunnel and use the server's address inside it. Roadstr does not contain a VPN: bring the tunnel up first.
  • A public name with a real certificate needs no tick, but then the search endpoint is open to the internet — restrict who can reach it.

What each side sees

Your instance sees the words you search, the name of your town for “near me” searches and the address the phone connects from; no coordinates, cookies or account. The search engines see the server's address, not the phone's. Use test connection in the web results settings to diagnose problems; strict sources makes Roadstr refuse an instance whose engine list it cannot read.

Public transport: MOTIS (planned)

Roadstr reads Transitous. An optional self-hosted MOTIS endpoint is on the roadmap, to spare the community server. Until then, the way to improve coverage is to add feeds to Transitous — see Public transport.

Nostr relays

For favourites sync you can add your own relay (Settings → Sync favorites → Your own relay). Road reports use the public relays.

Clone this wiki locally