gendesign/docs/osrm-routing.md
bot-backend 4fe20a9cbd
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / build-worker (push) Successful in 46s
Deploy / deploy (push) Successful in 1m18s
Deploy / build-frontend (push) Successful in 31s
Deploy / build-backend (push) Successful in 33s
feat(devops): self-hosted OSRM routing engine for site-finder (#39) (#1929)
2026-06-26 19:18:21 +00:00

6.3 KiB
Raw Blame History

OSRM routing engine (self-hosted) — #39

Self-hosted OSRM для site-finder /analyze: реальные дорожные / пешие расстояния до POI вместо straight-line ST_Distance(geography).

Scope этого PR — INFRA ONLY. Здесь стоит контейнер + build-скрипт + healthcheck. Интеграция в /analyze (замена ST_Distance на OSRM route/table) — отдельный follow-up (A2 изохроны, A3 per-category routing-decay). Backend пока к osrm НЕ ходит.

Архитектура

backend ──http://osrm:5000──▶ osrm (osrm-routed --algorithm mld)
                                 │ volume ./data/osrm:/data
                                 └─ /data/sverdlovsk.osrm*  (MLD-граф, ~ХХХ MB)
  • Compose service osrm в docker-compose.prod.yml, сеть default (project gendesign).
  • Наружу НЕ публикуется — нет ports:. Достижим только из backend по http://osrm:5000. Caddy его не проксирует (routing — internal API, не должен быть публичным).
  • mem_limit: 1.5g, restart: unless-stopped.
  • Граф (/data/*.osrm*) НЕ в git (.gitignoredata/osrm/*). Строится offline на VPS.

Build / refresh графа

Скрипт: scripts/build_osrm.sh. Запускается вручную на VPS (НЕ часть deploy.yml — download+build тяжёлые).

cd /opt/gendesign
bash scripts/build_osrm.sh            # car-профиль, Свердл-clip (default)

Источник pbf и решение по региону

Geofabrik не публикует Свердловскую область отдельно — есть только Уральский ФО (≈600 MB). Скрипт по умолчанию (CLIP=1) скачивает Ural-FO и обрезает по bbox Свердл. обл. через osmium extract → легче граф, меньше RAM в runtime.

Режим Команда pbf Граф в RAM (warm) Когда
Свердл-clip (default) bash scripts/build_osrm.sh clip из Ural-FO ~0.81.2 GB рекоменд., extensibility на обл
ЕКБ-tight EKB_TIGHT=1 bash scripts/build_osrm.sh узкий bbox ЕКБ ~0.40.6 GB если RAM на VPS критична
Ural-FO zero-clip CLIP=0 bash scripts/build_osrm.sh весь Ural-FO ~1.5 GB+ если нужен запас на соседние регионы

bbox Свердл (с запасом): lon 57.2..66.2, lat 56.0..62.0. ЕКБ-tight: lon 59.0..62.5, lat 56.2..58.2.

Pipeline (MLD, не CH)

--algorithm mld в compose требует pipeline extract → partition → customize (скрипт делает это через тот же osrm/osrm-backend образ). osrm-contract — это CH-алгоритм, он несовместим с --algorithm mld, поэтому НЕ используется.

Walking-профиль (Phase-2, опционально)

Issue хочет оба профиля (car + foot) eventually. Этот PR car-first. Пеший граф:

WALK=1 bash scripts/build_osrm.sh     # дополнительно соберёт sverdlovsk-foot.osrm*

Для пешего routing нужен второй compose-service (он не добавлен в этом PR, чтобы не плодить idle-контейнер пока /analyze не интегрирован). Блок для будущего:

  osrm-walk:
    image: osrm/osrm-backend:latest
    restart: unless-stopped
    command: osrm-routed --algorithm mld --max-table-size 8000 /data/${OSRM_REGION:-sverdlovsk}-foot.osrm
    volumes: [./data/osrm:/data]
    mem_limit: 1g
    healthcheck:
      test: ["CMD-SHELL", "timeout 3 bash -c '</dev/tcp/127.0.0.1/5000' || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 40s
    networks: [default]

Backend ходил бы к нему по http://osrm-walk:5000.

Monthly refresh

osm.pbf на Geofabrik обновляется ежедневно. Граф освежать ~ежемесячно:

0 4 1 * * cd /opt/gendesign && bash scripts/build_osrm.sh >> /var/log/osrm-build.log 2>&1 \
  && docker compose -p gendesign -f docker-compose.prod.yml up -d --force-recreate --no-deps osrm

Скрипт idempotent: wget -N качает только если на сервере новее, граф перестраивается overwrite.

Развёртывание (что выполняет оркестратор на VPS)

cd /opt/gendesign
git fetch origin main && git reset --hard origin/main     # подтянуть compose + скрипт

# 1. Build графа (~3050 мин, ~600MB download + ~3GB peak RAM на extract)
bash scripts/build_osrm.sh

# 2. Поднять контейнер
docker compose -p gendesign -f docker-compose.prod.yml up -d osrm

# 3. Verify (curl ВНУТРИ образа нет — используем sidecar curl в той же сети)
docker run --rm --network gendesign_default curlimages/curl:8 -fsS \
  'http://osrm:5000/route/v1/driving/60.6,56.84;60.65,56.86'
# ожидаем JSON: {"code":"Ok","routes":[{...}], ...}

Healthcheck

Compose-healthcheck — TCP-probe порта 5000 через bash /dev/tcp (образ osrm/osrm-backend НЕ содержит curl/wget, HTTP-probe падал бы на missing binary). Полный route-probe — verify-команда выше (sidecar curl).

Риски / open

  • RAM на Beget VPS: +~1 GB warm для Свердл-clip. Перед up -d osrm проверить свободную RAM (free -h). Если жмёт — EKB_TIGHT=1 (~0.40.6 GB) или upgrade plan.
  • Build на VPS медленный (50+ мин). Альтернатива: собрать локально и scp data/osrm/*.osrm* в /opt/gendesign/data/osrm/.
  • Размер pbf неточен: Ural-FO ≈600 MB на скачку; «1.5GB» из issue — оценка по всему ФО + intermediate-файлы на диске во время build (нужно ~5 GB свободного диска).