Getting Started with OSRM on Azure Container Instances
OSRM (Open Source Routing Machine) is a "Modern C++ routing engine for shortest paths in road networks." Apparently, it's what powers part of the MapBox Directions and Matrix services. It's really easy to get started using the provided Docker containers, and in this article I'll show how to do the "Quick Start" tutorial without leaving the browser, using Azure Cloud Shell and Azure Container Instances.
1. Download OpenStreetMap data #
OSRM uses OpenSteetMap (OSM) .pbf files as raw material.
Open Azure Cloud Shell, go to the clouddrive
folder and download a .pbf file from Geofabrik (Berlin is used in the tutorial).
Azure Cloud Shell uses Azure File storage to persist files accross sessions. In order to use the downloaded file, you need to locate the mounted file share.
Cloud Shell creates three resources on your behalf in the supported region that's nearest to you:
- Resource group:
cloud-shell-storage-<region>
- Storage account:
cs<uniqueGuid>
- File share:
cs-<user>-<domain>-com-<uniqueGuid>
2. Pre-process the data #
Three consecutive steps are required to prepare the data for OSRM. For each step we run a Container Instance named osrm
. Create a resource group to hold the Container Intances. Mine is called maps
.
Run osrm-extract #
Create a Container Instance using the following command:
az container create \
-g maps \
--name osrm \
--location eastus \
--image osrm/osrm-backend \
--command-line "osrm-extract -p /opt/car.lua /mnt/osrm/berlin-latest.osm.pbf" \
--azure-file-volume-share-name <cloud-shell-file-share> \
--azure-file-volume-account-name <cloud-shell-storage-account> \
--azure-file-volume-account-key <cloud-shell-storage-account-key> \
--azure-file-volume-mount-path /mnt/osrm \
--restart-policy Never
You can attach to the container output with:
az container attach -g maps --name osrm
If the container ran successfully, the logs should end with this line:
[info] RAM: peak bytes used: 233426944
⚠️ For bigger .pbf files, more memory is needed to pre-process and serve the data. Use the --memory
switch to allocate more RAM to the Container Instance. For instance, around 8 GB of RAM is needed to run osrm-extract
for Canada. Running osrm-extract
for North America required tens of GBs of RAM, way more than what you can allocate to a single Container Instance.
Run osrm-partition
#
We can reuse the same Container Instance to run osrm-partition
.
az container create \
-g maps \
--name osrm \
--location eastus \
--image osrm/osrm-backend \
--command-line "osrm-partition /mnt/osrm/berlin-latest.osrm" \
--azure-file-volume-share-name <cloud-shell-file-share> \
--azure-file-volume-account-name <cloud-shell-storage-account> \
--azure-file-volume-account-key <cloud-shell-storage-account-key> \
--azure-file-volume-mount-path /mnt/osrm \
--restart-policy Never
To check the container state, run this command:
az container show -g maps --name osrm --query "containers[0].instanceView.currentState.state"
It should either say "Running", or "Terminated" when it's done.
Run osrm-customize
#
The third and last step is osrm-customize
.
az container create \
-g maps \
--name osrm \
--location eastus \
--image osrm/osrm-backend \
--command-line "osrm-customize /mnt/osrm/berlin-latest.osrm" \
--azure-file-volume-share-name <cloud-shell-file-share> \
--azure-file-volume-account-name <cloud-shell-storage-account> \
--azure-file-volume-account-key <cloud-shell-storage-account-key> \
--azure-file-volume-mount-path /mnt/osrm \
--restart-policy Never
After this is finished, the Container Instance needs to be deleted:
az container delete -g maps --name osrm
3. Run the OSRM server #
The data is now ready to be served by OSRM. We create a new Container Instance that will accept requests on port 80.
az container create \
-g maps \
--name osrm \
--location eastus \
--image osrm/osrm-backend \
--command-line "osrm-routed --port 80 --algorithm mld /mnt/osrm/berlin-latest.osrm" \
--azure-file-volume-share-name <cloud-shell-file-share> \
--azure-file-volume-account-name <cloud-shell-storage-account> \
--azure-file-volume-account-key <cloud-shell-storage-account-key> \
--azure-file-volume-mount-path /mnt/osrm \
--dns-name-label osrm-on-aci \
--ports 80
The --dns-name-label osrm-on-aci
switch means that the server will be reachable at http://osrm-on-aci.eastus.azurecontainer.io/
Let's verify that it's working by requesting a route: route/v1/driving/13.388860,52.517037;13.385983,52.496891
{
"code":"Ok",
"routes":[
{
"geometry":"mfp_I__vpAn_AuIv@vZl]qNlTk@rKqBwAxT",
"legs":[
{
"steps":[
],
"distance":2882.3,
"duration":316.8,
"summary":"",
"weight":330.9
}
],
"distance":2882.3,
"duration":316.8,
"weight_name":"routability",
"weight":330.9
}
],
"waypoints":[
{
"hint":"yCACgEYhAoAUAAAAIAAAAAcAAAAAAAAAeOI0QY6li0FoZYRAAAAAAAoAAAAQAAAABAAAAAAAAADgAAAAAEzMAKlYIQM8TMwArVghAwEA3wrJP-r_",
"name":"Friedrichstraße",
"location":[
13.3888,
52.517033
]
},
{
"hint":"mAgAgFYYAoBtAAAAhgAAAAAAAAAAAAAACiuSQjMSs0IAAAAAAAAAAG0AAACGAAAAAAAAAAAAAADgAAAAgEDMAKYIIQP_QMwA-wkhAwAArxHJP-r_",
"name":"Obentrautstraße",
"location":[
13.385856,
52.49655
]
}
]
}
Success! 🎉
See the documentation for information on the other services offered by OSRM.
In order to avoid bad surprises at the end of the month, don't forget to delete the Container Instance when you're done: az container delete -g maps --name osrm