Back to the blog

Setting up a topographic elevation server (OpenTopoData): Docker, datasets and a systemd service

A topographic server (or elevation server) exposes an HTTP API that returns the altitude of one or more GPS coordinates. It is typically used for:

  • the elevation profile (climb) of a route,

  • enriching GPX tracks,

  • slope computation / terrain analysis,

  • showing altitude in an application.

In this guide, we set up OpenTopoData, an open-source elevation API, with Docker, make it “production-friendly” with systemd, and go through dataset management (SRTM / EU-DEM).

 

OpenTopoData

 

1) Installation

Prerequisites

Install Docker.

OpenTopoData ships with a Docker image; it is the simplest and most reproducible path.

 

Getting the project and building the image

Clone, then build:

git clone https://github.com/ajnisbet/opentopodata.git
cd opentopodata/
make build
make run
  • make build: builds the Docker image

  • make run: starts the container (optional, for a quick test)

 

Starting the server with Docker (direct command)

You can also start it without make run, straight from the CLI, mounting the data directory read-only:

docker run --rm -it --volume "/home/www/opentopodata/data:/app/data:ro" -p 5000:5000 opentopodata:`cat VERSION`

Explanation:

  • --volume "/home/www/opentopodata/data:/app/data:ro": makes your datasets available to the container

  • -p 5000:5000: exposes the API on port 5000

  • opentopodata:`cat VERSION`: runs the tagged version matching the repository

 

Plan your own route

MapPlanner helps you calculate distances, elevation, duration and plan your hikes, runs and bike rides on an interactive map.

  • Automatic distance & elevation calculation
  • Topographic, satellite maps
  • GPX/KML export for your GPS
  • Real-time GPS tracking

2) Creating a systemd service (automatic startup)

The goal: run OpenTopoData as a service that restarts automatically and is managed with systemctl.

Create the service:

sudo nano /etc/systemd/system/elevation.service

Content:

[Unit]
Description=OpenTopoData elevation API
After=network.target

[Service]
Type=simple

User=deploy
Group=deploy

WorkingDirectory=/home/www/opentopodata
ExecStart=docker run --rm --volume '/home/www/opentopodata/data:/app/data:ro' --network host opentopodata:1.10.0

# if we crash, restart
TimeoutSec=30
Restart=on-failure

TimeoutStartSec=120
TimeoutStopSec=30

# output goes to the journal
StandardOutput=journal
StandardError=journal

SyslogIdentifier=opentopodata-elevation

[Install]
WantedBy=multi-user.target

Key points for the service to work:

  • pin the version (1.10.0)

  • do not use the -t and -i options

  • use the host network (--network host) so the API can be called locally on port 5000; the -p option is then useless

  • the service user must belong to the docker group

Enable and start it:

sudo systemctl daemon-reload
sudo systemctl enable elevation.service
sudo systemctl start elevation.service
sudo systemctl status elevation.service

Alternative: installing without Docker

It can be installed without Docker:

https://www.opentopodata.org/notes/running-without-docker/

Performance is the same with or without Docker.

 

3) Choosing and configuring the topographic data

OpenTopoData supports several datasets. Two useful pages:

After adding data, the Docker image has to be rebuilt.

 

Datasets in use: history and current setup

In the current version, only SRTM30 data is used, for the whole world.

Previous setup:

  • Europe: EU-DEM

  • North America: SRTM30

  • Elsewhere: SRTM90

 

Comparing the data

  • SRTM30: the most precise data (2x slower than SRTM90)

  • SRTM90: approximate data (the fastest)

  • EU-DEM: 25 m, but less precise than SRTM30 (3x slower than SRTM90)

 

4) World: SRTM (SRTM30m / SRTM GL1)

OpenTopoData dataset (SRTM):

Create an account on OpenTopography:

Total size of the tif files: 126 GB.

The data sits on S3-compatible storage; to download it, first install aws-cli:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

Then, in the target directory:

aws s3 cp s3://raster/SRTM_GL1/ . --recursive --endpoint-url https://opentopography.s3.sdsc.edu --no-sign-request

The global VRT file is downloaded too (-32768 for areas without data).

 

Optimizing: converting to compressed GeoTIFF

If the files are not tif already (or to optimize I/O), convert them to compressed GeoTIFF:

Install GDAL:

sudo apt install gdal-bin

Conversion:

for f in *.hgt.zip; do gdal_translate -co COMPRESS=DEFLATE -co PREDICTOR=2 "$f" "${f%.*}.tif"; done

Cleanup:

rm *.zip

Time to generate the TIF files for North America: 30 min.

 

Deploying the data to the server and rebuilding

Copy the generated tif files to the server, update the config.yaml file and rebuild the Docker image:

make build

Restart the service:

sudo systemctl restart elevation.service

Test (if the server accepts local requests):

curl "http://localhost:5000/v1/srtm30m?locations=57.688709,11.97"

 

5) Europe: EU-DEM

OpenTopoData dataset (EU-DEM):

Download: since January 2024, EU-DEM is no longer distributed by Copernicus. The OpenTopoData page above says where to get a copy of the dataset.

Steps:

  1. Download all the data at once

  2. Extract all the files

  3. Keep only the TIF files

Total size of the tif files: 38 GB.

 

Adding EU-DEM to OpenTopoData

In the opentopodata directory:

mkdir ./data/eudem

Copy the TIF files into it (rename them as described here: https://www.opentopodata.org/datasets/eudem/)

Create the config.yaml file declaring the dataset:

datasets:
- name: eudem25m
  path: data/eudem/
  filename_epsg: 3035
  filename_tile_size: 1000000

Rebuild and restart the container:

make build && make run

Test (if the server accepts local requests):

curl "http://localhost:5000/v1/eudem25m?locations=57.688709,11.976404"

 

6) Getting a specific continent for SRTM

Reference:

https://github.com/graphhopper/graphhopper/blob/master/core/src/main/resources/com/graphhopper/reader/dem/

Rename the file extension and prepend the URL to each line.

 

7) Other elevation services (alternatives)

Related articles

What our Explorer users say

⭐⭐⭐⭐⭐

I planned a 5-mile running loop around my neighborhood in minutes. The distance and pace estimate were spot on for my morning run before work.

Sarah K. New runner
⭐⭐⭐⭐⭐

With the isochrone mode, I plan my hikes in no time! I instantly see how far I can go with my available time. GPS tracking keeps me on trail in the Rockies.

Jessica W. Passionate hiker
⭐⭐⭐⭐⭐

We prepared a 25-mile cycling loop with friends and exported the GPX track. Everyone followed the same route on their Garmin without getting lost. Perfect organization!

Mike R. Weekend cyclist
⭐⭐⭐⭐⭐

Before a hike in Shenandoah, I checked the elevation and duration. The route followed real trails, which saved me from unpleasant surprises. Very reliable!

Emily L. Beginner hiker
⭐⭐⭐⭐⭐

I wanted an easy walk for my kids. I set a short max distance and MapPlanner helped me create the perfect loop. We had a wonderful family afternoon.

David N. Family outing
⭐⭐⭐⭐⭐

I love planning my outings in advance. I saved several routes for the weekends. It saves me so much time compared to figuring it out on the go.

Karen G. Occasional hiker
⭐⭐⭐⭐⭐

By exploring the routes around my area, I discovered great trails I didn’t know about. MapPlanner opened new places for me to explore right in my backyard.

Chris P. Trail discovery
⭐⭐⭐⭐⭐

I keep track of my progress with the history feature. Comparing my running pace and distance over the months keeps me motivated and accountable.

Ashley T. Performance tracking
⭐⭐⭐⭐⭐

For our MTB group ride, we created the route and sent the GPX to everyone. Nobody got separated — the whole group stayed together from start to finish.

Brian B. Club activity
⭐⭐⭐⭐⭐

I love taking photos while hiking. MapPlanner automatically places my pictures on the map. It’s awesome to review the route and share it with friends.

Lauren F. Discovery outing
⭐⭐⭐⭐⭐

Depending on the activity, I switch the map style: topo for the mountains, street for the city, satellite to scout terrain. It makes route planning super intuitive.

Tyler S. Experienced hiker
⭐⭐⭐⭐⭐

MapPlanner now estimates my times based on my own pace. I know exactly how long my next run will take. Perfect for squeezing in a workout on a tight schedule.

Rachel J. Aspiring runner

Popular routes

Discover the most popular routes near you

Miles at the Meadow - 5k / 10K (2 loops)
pete.augrom
Running
Very easy

Miles at the Meadow - 5k / 10K (2 loops)

3.095mi
•
33m
•
5.63mph
Virginia - The Plains
Fusion Invitational High School 5K Course
nm8zkrv8hk
Running
Easy

Fusion Invitational High School 5K Course

3.201mi
•
34m
•
5.65mph
Colorado - Commerce City
ada
rajan
Running
Strenuous

ada

11.669mi
•
4h10m
•
2.8mph
New York - New York
Route 2 - Prayer Walk Connecting Churches (Ferguson)
SR St. Louis
Walk
Very easy

Route 2 - Prayer Walk Connecting Churches (Ferguson)

1.441mi
•
31m
Missouri - Ferguson
2026 HHHH 25mi Route
buschlive
Bike
Moderate

2026 HHHH 25mi Route

24.79mi
•
2h30m
•
9.92mph
Texas - Hutchins
Central park
Fibula
Running
Moderate

Central park

6.393mi
•
1h
•
6.39mph
New York - New York
Miles at the Meadow - 1 mile
pete.augrom
Running
Very easy

Miles at the Meadow - 1 mile

1.012mi
•
11m
•
5.52mph
Virginia - The Plains
Chincoteague National Wildlife Refuge
Gaynor
Bike
Very easy

Chincoteague National Wildlife Refuge

9.532mi
•
2h
•
4.77mph
Virginia - Chincoteague Island