Step-by-Step OSRM Docker Setup on AWS EC2

To deploy Open Source Routing Machine (OSRM) on AWS EC2 using Docker, provision a memory-optimized instance, attach a high-IOPS EBS volume, install the official Docker Engine, preprocess an OpenStreetMap .osm.pbf extract, and launch the routing daemon on port 5000. Containerizing the entire pipeline eliminates host-level dependency conflicts, guarantees reproducible builds, and aligns with modern infrastructure practices for Deploying OSRM with Docker for Local Routing.

Infrastructure & Resource Requirements

OSRM uses memory-mapped files for sub-millisecond routing queries. Your AWS configuration must accommodate the full graph load at startup:

  • Instance Family: r6i or r7i (high memory bandwidth). Avoid burstable t3/t4g types; preprocessing will throttle CPU credits.
  • RAM Allocation: City-scale ≥8 GB, State/Country ≥16–32 GB, Continental ≥64 GB+. The .osrm dataset loads entirely into RAM.
  • Storage: gp3 EBS with ≥3000 IOPS and ≥125 MB/s throughput. Preprocessing is heavily I/O-bound. See Amazon EBS Volume Types for provisioning guidance.
  • Host OS: Ubuntu 22.04/24.04 LTS or Amazon Linux 2023.
  • Algorithm: Multi-Level Dijkstra (MLD) is the default. It supports dynamic traffic updates and faster isochrone generation compared to legacy Contraction Hierarchies (CH).

Step 1: Provision EC2 & Mount High-IOPS Storage

Launch your instance via AWS Console or CLI. Attach a secondary gp3 EBS volume (500 GB minimum for regional datasets) and mount it to /mnt/osrm-data. Configure the security group to allow inbound TCP 22 (SSH) and TCP 5000 (OSRM HTTP API). Restrict port 5000 to your VPC CIDR or place a reverse proxy in front for public exposure.

# Identify the new block device (usually /dev/xvdf or /dev/nvme1n1)
lsblk

# Format as ext4 and mount
sudo mkfs.ext4 /dev/xvdf
sudo mkdir -p /mnt/osrm-data
sudo mount /dev/xvdf /mnt/osrm-data

# Persist across reboots
echo '/dev/xvdf /mnt/osrm-data ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab

Step 2: Install Docker Engine

Use the official Docker repository to ensure version parity, receive security patches, and access the latest overlay2 storage driver. Avoid the default docker.io package from Ubuntu’s repositories, which frequently lags upstream.

# Install prerequisites
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings

# Add Docker's official GPG key & repository
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install packages & configure user permissions
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER && newgrp docker

Verify with docker run --rm hello-world. For troubleshooting or alternative distros, consult the official Docker Engine Installation Guide.

Step 3: Download & Preprocess OSM Data

OSRM requires a routing profile (e.g., car.lua, foot.lua) and a geographic extract. Download the .osm.pbf file from Geofabrik or BBBike, then run the three-stage MLD pipeline inside Docker.

# Set working directory and download data
cd /mnt/osrm-data
sudo curl -LO https://download.geofabrik.de/north-america/us/california-latest.osm.pbf

# 1. Extract: Parse OSM XML/PBF into routing graph
docker run -t -v /mnt/osrm-data:/data \
  ghcr.io/project-osrm/osrm-backend \
  osrm-extract -p /opt/car.lua /data/california-latest.osm.pbf

# 2. Partition: Divide graph for parallel processing
docker run -t -v /mnt/osrm-data:/data \
  ghcr.io/project-osrm/osrm-backend \
  osrm-partition /data/california-latest.osrm

# 3. Customize: Apply traffic weights and finalize MLD structures
docker run -t -v /mnt/osrm-data:/data \
  ghcr.io/project-osrm/osrm-backend \
  osrm-customize /data/california-latest.osrm

Profile selection dictates routing behavior. Review available Lua profiles and customization options in the OSRM Backend Profiles Documentation before extraction.

Step 4: Launch the Routing Server

Start the osrm-routed daemon as a detached container. Map port 5000, mount the preprocessed data directory, and apply memory limits to prevent OOM kills during peak query loads.

docker run -d \
  --name osrm-server \
  --restart unless-stopped \
  --memory="90%" \
  --memory-swap="-1" \
  -p 5000:5000 \
  -v /mnt/osrm-data:/data \
  ghcr.io/project-osrm/osrm-backend \
  osrm-routed --algorithm mld --max-table-size 1000 /data/california-latest.osrm

Key flags:

  • --algorithm mld: Enables dynamic edge weights and faster multi-destination queries.
  • --max-table-size 1000: Limits distance matrix requests to prevent memory exhaustion.
  • --memory="90%": Reserves 10% RAM for host OS and Docker daemon overhead.

Step 5: Verify & Integrate

Test the HTTP API with a direct curl request. A successful response returns a JSON route object with geometry, duration, and distance.

curl "http://localhost:5000/route/v1/driving/-118.2437,34.0522;-117.1611,32.7157?overview=full&geometries=polyline6"

The server exposes RESTful endpoints for /route, /table, /match, and /nearest. For production deployments, route traffic through Nginx or AWS Application Load Balancer, enable HTTPS, and implement request rate limiting.

Once validated, the API integrates seamlessly into broader Python Routing Engines & Isochrone Mapping workflows. Use requests or httpx to query the endpoint, parse polyline geometries with polyline or geopandas, and feed routing results into logistics optimization models or spatial dashboards.