Files

4.1 KiB
Raw Permalink Blame History

nominatim

Self-hosted Nominatim (OpenStreetMap geocoding) for address search / soft validation on the homelab LAN. Pure OSM data, no API key, no per-request cost.

Companion to Ditch_The_Agent/OSRM (routing) on ai-server-4080 (10.0.0.128).

OSRM ≠ Nominatim. OSRM routes lat/lng. Nominatim turns addresses into coordinates (and reverse). Share the .osm.pbf only — never mount OSRM .osrm* graph files into this stack.

Consumers (e.g. monica_site) should use:

NOMINATIM_BASE_URL=http://10.0.0.128:8089

Provisioning: server-infra#16.


What you get

  • mediagis/nominatim Docker image (upstream)
  • HTTP API on host port 8089 (container 8080):
    • /search — forward geocode
    • /reverse — reverse geocode
    • structured params: street, city, state, postalcode, country
  • First boot imports a local PBF into an internal Postgres/PostGIS volume

Hardware sizing (rough)

Region PBF size Import RAM Serve RAM Disk (DB)
US single state (e.g. Ohio) ~200400 MB ~816 GB ~24 GB ~1030 GB
US Midwest extract ~13 GB ~1632 GB ~48 GB ~40100 GB
Full US ~10+ GB 64 GB+ 16 GB+ 200 GB+

Import is one-shot and slow. Prefer the smallest extract that covers your service area (Ohio / Midwest for monica_site). Full US is optional and expensive on disk/RAM.


Quick start

# from this directory
mkdir -p data
cp .env.example .env
# edit NOMINATIM_PASSWORD + NOMINATIM_PBF_FILE if needed

# 1. Place (or symlink) a Geofabrik PBF into ./data/
#    Reuse the same PBF used for OSRM — copy/symlink, do not move OSRM's copy
#    if OSRM still needs it.
ln -sf /path/to/OSRM/data/us-latest.osm.pbf data/region.osm.pbf
# or download a smaller extract:
# curl -L -o data/ohio-latest.osm.pbf \
#   https://download.geofabrik.de/north-america/us/ohio-latest.osm.pbf

# 2. First up runs the import (long). Keep the container running afterward.
docker compose up -d

# 3. Watch import / API ready
docker compose logs -f nominatim

# 4. Smoke test
curl -sG 'http://localhost:8089/search' \
  --data-urlencode 'q=Akron, OH' -d 'format=json' -d 'limit=1'

Structured address check:

curl -sG 'http://localhost:8089/search' \
  -d 'street=123 Main St' \
  -d 'city=Akron' \
  -d 'state=Ohio' \
  -d 'postalcode=44301' \
  -d 'country=USA' \
  -d 'format=json' \
  -d 'limit=1'

Running the container

docker compose pull
docker compose up -d
docker compose logs -f nominatim
docker compose ps
docker compose restart nominatim
docker compose stop
docker compose down   # keeps named volume with DB unless -v

Set NOMINATIM_PBF_FILE in .env to the filename under ./data/ (default region.osm.pbf).

Import only runs when the Postgres data volume is empty. To re-import:

docker compose down -v   # destroys nominatim-pgdata
# ensure data/*.osm.pbf is present
docker compose up -d

Homelab LAN (adama / roslin → ai-server-4080)

Default bind is 0.0.0.0:8089 so LAN hosts can reach it. Open UFW to the LAN only — not the public internet:

sudo ufw allow from 10.0.0.0/24 to any port 8089 proto tcp comment 'Nominatim homelab LAN'
sudo ufw status

Verify from another host:

curl -sG 'http://10.0.0.128:8089/search' \
  --data-urlencode 'q=Akron, OH' -d 'format=json' -d 'limit=1'

Local-only bind: set NOMINATIM_BIND_HOST=127.0.0.1 in .env.


Relation to OSRM

OSRM (:5000) Nominatim (:8089)
Job Route coordinates Geocode addresses
Input .osrm* graphs .osm.pbf → Postgres
Share PBF only

Typical app flow: Nominatim search → lat/lng → (optional) OSRM route.


License / attribution

Nominatim is GPL-2.0. OpenStreetMap data is © OpenStreetMap contributors, ODbL. Attribute on any UI that surfaces geocoded results:

"Geocoding © OpenStreetMap contributors, via Nominatim."