How To Set Up An OSRM Server On Ubuntu 14.04
How To Set Up An OSRM Server On Ubuntu 14.04
14.04
Introduction
The OpenStreetMap project consists of raw map data, collected and aggregated by thousands of
users. However, its open access policy sparked a number of collateral projects, which
collectively cover many of the features typically offered by commercial mapping services.
The most obvious advantage in using OpenStreetMap-based software over a commercial solution
is economical convenience, because OpenStreetMap comes as free (both as in beer and as in
speech) software. The downside is that it takes a little configuration in order to setup a working
web service.
This tutorial covers the configuration and maintenance of a web service which can answer
questions such as:
How long does it take to get from point A to point B with a car, or by foot?
The software that makes this possible is an open-source project called Open Source Routing
Machine (OSRM), which is based on the OpenStreetMap data. Functionalities to embed
OpenStreetMaps in Web pages are already provided out-of-the-box by APIs such as OpenLayers.
Prerequisites
To follow this tutorial, you will need:
Some of the operations in this tutorial, such as building OSRM from source and the preprocessing phases, are memory intensive. On low-memory Droplets, these operations may fail,
which is why it is necessary to allocate a swap file.
The web service does not normally require additional swap while running, so this swapfile can
be removed after the setup is complete. However, when serving large maps, a small swap file
might actually be necessary, especially in low-memory Droplets. If so, follow the instructions in
the above tutorial to make the swap file persistent.
Then, we turn on Ubuntu's unattended security upgrades. To do this, we first need to install the
necessary packages.
sudo apt-get install unattended-upgrades
Add the following line at the end of the file, then save and close it.
APT::Periodic::Unattended-Upgrade "1";
Our web service will be based on a map export from OpenStreetMap. There are several possible
ways to obtain a map export.
The first option is to point your browser to the OpenStreetMap's export page, zoom on the
interested area, and click on Export. (You may need to use one of the other sources if the native
export does not work; Overpass API is a good choice.) This will allow you to finely choose
which areas to include in your map and, in general, to cut down on the pre-processing times.
However, there are limits on the size of the export you can get from the OSRM website, so you
might want to download a ready-made export. A number of services, such as Geofabrik and
Mapzen offer updated and ready-made map exports of countries and selected metropolitan areas,
which are good for most use cases.
Whichever method you use, copy the URL of the export and download it onto your Droplet.
wget -O map.osm url_of_the_export
You should now have a file named map.osm in your working directory.
OSRM is a fairly complex piece of software and also relies on a number of libraries. We can
install the required dependencies with the following command.
sudo apt-get install libboost-all-dev libtbb-dev liblua5.2-dev libluabind-dev
libstxxl-dev libxml2 libxml2-dev libosmpbf-dev libbz2-dev libprotobuf-dev
These dependencies are used for various things. Lua is used to define custom speed profile
scripts, e.g. defining that on a secondary road, in absence of limits, a car goes on average at 80
km/h, and that on a gravel road the average speed is 50 km/h. STXXL is a version of C++'s
standard library which uses disk space as memory, used to manipulate large files. LibXML and
Protocol buffers are used to load, write, and manipulate OSM files, and Boost and TBB are used
for parallelization and to represent data structures.
The next step is to use CMake to generate the build files. It is recommended to build OSRM in a
dedicated build directory in the source code root, to avoid polluting the source directories with
temporary build files.
Create a build directory.
mkdir build
Finally, we will generate the build files with cmake. This command will generate a number of
directories and Makefiles in the build directory tree.
cmake ..
If you get an error here, make sure you have enabled swap via the instructions in the
prerequisites.
Next, compile and install OSRM.
sudo make install
osrm-extract which opens the map file and runs a first pre-processing step on
the data.
traveling times for all the map edges according to a given Lua speed profile.
osrm-routed the actual web service daemon, which allows us to query for
Before running the web service, we need to pre-process our map export. Because we have
installed the needed binaries in the system path, we can do this from anywhere. For the purpose
of this tutorial, we will run the pre-processing in the root of the osrm directory we have created.
First, move to the osrm directory.
cd ~/osrm
The map pre-processing is quite memory intensive. For this reason, OSRM uses a library called
STXXL to map its internal operations on the hard disk. STXXL relies on a configuration file
called .stxxl, which lives in the same directory where you are running your software, to
determine how much space is dedicated to the STXXL data structures. Depending on our
Droplet's capacity and on the size of the map we wish to process, we need to write a suitable
.stxxl configuration file, allocating enough memory for the operations.
Create and open .stxxl for editing.
nano .stxxl
The file must contain a single line with format disk=path,capacity,access, where path is the
path where the allocation file will be placed, capacity is the capacity of the file, and access is a
file access implementation.
Here is an example of a .stxxl file. You can paste this into .stxxl, but may want to change the
size of the file based on the map you're using and the size of your Droplet. See the
documentation for advanced options.
disk=/tmp/stxxl,10G,syscall
Because the speed profile script might depend on some Lua functions defined in the profiles
library, we also create a symbolic link to it in the same directory by running the following two
commands.
ln -s osrm-backend/profiles/car.lua profile.lua
ln -s osrm-backend/profiles/lib
This step generates a bunch of files in the pre-processing directory, including map.osrm, which is
the input to the next step.
This step also produces some additional files needed by the web service, which we will set up in
the next section.
"name": "street_name",
"mapped_coordinate": [
latitude,
longitude
],
"status":0
If you get an error message instead of this, you may have chosen a set of coordinates outside of
the map boundaries or your query syntax might be wrong. For more available queries, check out
the server API.
You can now stop osrm-routed using CTRL+C.
Next, we add a configuration file for our Web services. Nginx uses two directories for its sitespecific configuration files: /etc/nginx/sites-available (all sites that can be served) and
/etc/nginx/sites-enabled (all sites that are being served). The standard way of adding a site
is to add its configuration file to sites-available, and then link it symbolically in sitesenabled.
So first, we will add a configuration fime for OSRM to sites-available.
sudo nano /etc/nginx/sites-available/osrm.conf
Our configuration file will define an upstream that points at our web service and a server which
listens on port 80 and redirects a subset of the queries to our upstream.
Paste the follow configuration file into osrm.conf. You will need to specify two variables, which
are highlighted below: your server IP and a path (which will be used to access the web service, as
in http://your_server_ip/example_path).
upstream osrm {
server 0.0.0.0:5000;
}
server {
listen 80;
server_name your_server_ip;
location /example_path {
proxy_pass http://osrm/;
proxy_set_header Host $http_host;
}
}
Once you have saved the file, move to the sites-enabled directory.
cd /etc/nginx/sites-enabled
You should be able to access the Web service by pointing our browser to
http://your_server_ip/example_path. Note that you no longer need to specify the port. You
can now stop osrm-routed using CTRL+C.
By adding more upstreams and locations, and by running osrm-routed by specifying the port
with -p or --port we can run more instances of the Web service, and bind them to different
paths. This tutorial won't go into details about this, but you can check out the OSRM backend
documentation for more information.
In this step, we will install and configure Supervisor to keep Nginx running, allowing our web
service to be available through reboots.
Nginx now acts as a gateway for our web service. However, we have started it manually, so if we
log out from the system, it would stop running. In order to make our web services survive
through reboots and, in general, to make them recover from possible failures, we can use a tool
called Supervisor.
Supervisor is a process control system which mostly takes care of keeping services running
properly. Setting it up is quite easy. First, we install Supervisor itself.
sudo apt-get install supervisor
Then, we add our web service to the pool of services controlled by Supervisor by adding a new
configuration file.
sudo nano /etc/supervisor/conf.d/osrm.conf
The configuration file must contain a definition of this form for every web service we wish to
supervise, and the program name must be different for every web service.
Paste the below configuration into the osrm.conf file, then save and close it.
[program:osrm]
directory=/home/osrm/osrm
command=/usr/local/bin/osrm-routed -p 5000 map.osrm
user=osrm
What this configuration says is that we want the user osrm to keep the command
/usr/local/bin/osrm-routed -p 5000 map.osrm running, and that it must be run from the
specified directory, /home/osrm/osrm (which is how we can specify map.osrm as a relative path
in the command). In this example we specified the port for osrm-routed using -p so that
multiple programs can be added by increasing the port.
Once you save and close the file, restart Supervisor.
sudo service supervisor restart
RUNNING
This means that our web service is running. Because the upstream is pointing to port 5000,
Nginx will be able to serve it on the specified path.