Vincent Costel

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

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:

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