6.3 KiB
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на OSRMroute/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(projectgendesign). - Наружу НЕ публикуется — нет
ports:. Достижим только из backend поhttp://osrm:5000. Caddy его не проксирует (routing — internal API, не должен быть публичным). mem_limit: 1.5g,restart: unless-stopped.- Граф (
/data/*.osrm*) НЕ в git (.gitignore→data/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.8–1.2 GB | рекоменд., extensibility на обл |
| ЕКБ-tight | EKB_TIGHT=1 bash scripts/build_osrm.sh |
узкий bbox ЕКБ | ~0.4–0.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 графа (~30–50 мин, ~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.4–0.6 GB) или upgrade plan. - Build на VPS медленный (50+ мин). Альтернатива: собрать локально и
scpdata/osrm/*.osrm*в/opt/gendesign/data/osrm/. - Размер pbf неточен: Ural-FO ≈600 MB на скачку; «1.5GB» из issue — оценка по всему ФО + intermediate-файлы на диске во время build (нужно ~5 GB свободного диска).