Deploying OpenTripPlanner
Introduction
OpenTripPlanner (OTP) is an open-source platform for multimodal trip planning that combines public transit, walking, cycling, and driving into unified journey recommendations. Originally developed for TriMet (Portland’s transit agency), OTP has grown into a mature, widely-deployed solution used by transit agencies, cities, and transportation applications worldwide.
OTP processes transit schedules (GTFS data) and street networks (OpenStreetMap data) to build a routing graph that enables real-time trip planning. The platform provides both a web interface for end users and a powerful API for integration into mobile apps, websites, and other transportation services.
Key highlights of OpenTripPlanner:
- Multimodal Routing: Combine transit, walking, cycling, and driving in single trips
- Real-Time Updates: Support for GTFS-RT feeds for live arrival predictions
- Accessibility: Route planning for users with mobility restrictions
- Bike Share Integration: Include bike-sharing stations in trip options
- Flexible API: RESTful and GraphQL APIs for application integration
- Isochrone Maps: Visualize areas reachable within time limits
- Multiple Languages: Internationalized interface and directions
- Sandbox Extensions: Additional features like fare calculation and park-and-ride
- Scalable Architecture: Handle high query volumes with appropriate resources
- Open Data: Built on open standards (GTFS, GBFS, OpenStreetMap)
This guide walks through deploying OpenTripPlanner on Klutch.sh using Docker, importing transit data, and configuring the service for production use.
Why Deploy OpenTripPlanner on Klutch.sh
Deploying OpenTripPlanner on Klutch.sh provides several advantages:
Simplified Deployment: Klutch.sh automatically builds and deploys your trip planner. Push to GitHub, and your service deploys without complex orchestration.
Persistent Storage: Attach persistent volumes for your built graph and configuration. Avoid rebuilding the graph after container restarts.
HTTPS by Default: Klutch.sh provides automatic SSL certificates for secure API access and web interface.
Scalable Resources: Trip planning requires significant memory for large graphs. Allocate resources based on coverage area and expected query volume.
GitHub Integration: Store configuration in Git for version control. Update by pushing changes to your repository.
Custom Domains: Assign a professional domain for your trip planning service.
Always-On Availability: Your trip planner runs 24/7, providing consistent routing service for your applications.
Prerequisites
Before deploying OpenTripPlanner on Klutch.sh, ensure you have:
- A Klutch.sh account
- A GitHub account with a repository for your OTP configuration
- Basic familiarity with Docker and containerization concepts
- GTFS data for your transit agencies (publicly available from most agencies)
- OpenStreetMap data for your region (PBF format)
Understanding OpenTripPlanner Architecture
OpenTripPlanner consists of several components:
Graph Builder: Processes GTFS and OSM data to create a routing graph. This is typically run once or periodically when data updates.
OTP Server: Loads the pre-built graph and handles routing requests. This is the main production service.
Web Interface: A built-in interface for testing and demonstration, or integrate with custom frontends.
APIs: RESTful API and GraphQL endpoint for programmatic access.
Data Requirements
GTFS (General Transit Feed Specification): Transit schedules including routes, stops, times, and calendar information. Available from transit agencies.
OpenStreetMap Data: Street network for walking, cycling, and driving. Download regional extracts from Geofabrik.
Preparing Your Repository
Create a GitHub repository containing your Dockerfile and configuration.
Repository Structure
otp-deploy/├── Dockerfile├── build-config.json├── router-config.json├── otp-config.json├── .dockerignore└── README.mdCreating the Dockerfile
Create a Dockerfile for OpenTripPlanner:
FROM opentripplanner/opentripplanner:latest
# Create directoriesRUN mkdir -p /var/otp/graphs/default
# Copy configuration filesCOPY build-config.json /var/otp/build-config.jsonCOPY router-config.json /var/otp/router-config.jsonCOPY otp-config.json /var/otp/otp-config.json
# Set environment variablesENV JAVA_OPTS="-Xmx4G"
# Expose the OTP portEXPOSE 8080
# The default entrypoint handles both building and servingConfiguration Files
Create build-config.json for graph building:
{ "areaVisibility": true, "platformEntriesLinking": true, "osmWayPropertySet": "default", "transitServiceStart": "-P1Y", "transitServiceEnd": "P2Y"}Create router-config.json for routing behavior:
{ "routingDefaults": { "numItineraries": 5, "transferSlack": 120, "walkReluctance": 2.0, "stairsReluctance": 1.65, "bikeRentalPickupTime": 60, "bikeRentalDropoffTime": 30 }, "updaters": []}Create otp-config.json for general settings:
{ "otpFeatures": { "SandboxAPIMapboxVectorTilesApi": true, "SandboxAPITravelTime": true }}Environment Variables Reference
| Variable | Default | Description |
|---|---|---|
JAVA_OPTS | -Xmx2G | JVM memory allocation |
OTP_GRAPH_PATH | /var/otp/graphs | Path to graph files |
Deploying OpenTripPlanner on Klutch.sh
Follow these steps to deploy OpenTripPlanner:
- Check agency websites for GTFS downloads
- Use TransitFeeds for aggregated feeds
- Contact agencies directly for access
- Select HTTP as the traffic type
- Set the internal port to 8080
Obtain Transit Data
Download GTFS data from your transit agency. Many agencies publish feeds:
Obtain Street Network Data
Download OpenStreetMap data for your region:
# Example: Download data for a metro areawget https://download.geofabrik.de/north-america/us/oregon-latest.osm.pbfBuild the Graph
Before deploying, build the OTP graph locally or in a build container:
# Run OTP in build modedocker run -v /path/to/data:/var/otp/graphs/default \ opentripplanner/opentripplanner:latest --build --saveThis creates a graph.obj file in your data directory.
Push Your Repository to GitHub
Initialize and push your repository:
git initgit add Dockerfile *.json .dockerignore README.mdgit commit -m "Initial OpenTripPlanner configuration"git remote add origin https://github.com/yourusername/otp-deploy.gitgit push -u origin mainCreate a New Project on Klutch.sh
Navigate to the Klutch.sh dashboard and create a new project named “otp” or “trip-planner”.
Create a New App
Within your project, create a new app. Connect your GitHub account and select the repository containing your OTP Dockerfile.
Configure HTTP Traffic
In the deployment settings:
Set Environment Variables
Configure memory allocation:
| Variable | Value |
|---|---|
JAVA_OPTS | -Xmx4G (adjust based on graph size) |
Attach Persistent Volumes
Add persistent storage for the graph:
| Mount Path | Recommended Size | Purpose |
|---|---|---|
/var/otp/graphs | 20 GB | Built graph files |
/var/otp/data | 10 GB | GTFS and OSM source files |
Upload Graph Data
Upload your pre-built graph.obj to the persistent volume at /var/otp/graphs/default/.
Deploy Your Application
Click Deploy to start the build process. OTP will load the graph and start the server.
Access OpenTripPlanner
Once deployment completes, access the web interface at:
https://your-app-name.klutch.shUsing OpenTripPlanner
Web Interface
The built-in interface provides:
- Interactive map for selecting origin and destination
- Date and time selection for trip planning
- Mode selection (transit, walk, bike, etc.)
- Accessibility options
- Itinerary display with step-by-step directions
REST API
Query trips programmatically:
curl "https://your-app-name.klutch.sh/otp/routers/default/plan?fromPlace=45.5,-122.6&toPlace=45.4,-122.5&date=2024-03-15&time=08:00&mode=TRANSIT,WALK"GraphQL API
Use the GraphQL endpoint for flexible queries:
{ plan( from: {lat: 45.5, lon: -122.6} to: {lat: 45.4, lon: -122.5} date: "2024-03-15" time: "08:00" transportModes: [{mode: TRANSIT}, {mode: WALK}] ) { itineraries { duration walkDistance legs { mode from { name } to { name } } } }}Isochrone Analysis
Generate travel time maps:
curl "https://your-app-name.klutch.sh/otp/routers/default/isochrone?fromPlace=45.5,-122.6&date=2024-03-15&time=08:00&mode=TRANSIT,WALK&cutoffSec=1800&cutoffSec=3600"Real-Time Updates
GTFS-RT Integration
Add real-time updates to router-config.json:
{ "updaters": [ { "type": "real-time-alerts", "frequencySec": 30, "url": "https://transit-agency.com/gtfs-rt/alerts", "feedId": "agency" }, { "type": "vehicle-positions", "frequencySec": 30, "url": "https://transit-agency.com/gtfs-rt/vehicle-positions", "feedId": "agency" }, { "type": "stop-time-updater", "frequencySec": 30, "url": "https://transit-agency.com/gtfs-rt/trip-updates", "feedId": "agency" } ]}Bike Share Integration
Add GBFS feeds for bike sharing:
{ "updaters": [ { "type": "bike-rental", "frequencySec": 60, "sourceType": "gbfs", "url": "https://bikeshare.com/gbfs/gbfs.json" } ]}Graph Updates
Updating Transit Data
When GTFS data changes:
- Download new GTFS files
- Rebuild the graph with new data
- Upload the new graph.obj to your volume
- Restart the OTP server to load the new graph
Automating Updates
Consider setting up scheduled graph rebuilds:
- Create a separate build container/job
- Schedule weekly or monthly rebuilds
- Upload new graphs during low-traffic periods
- Restart the server to load updated data
Performance Optimization
Memory Allocation
OTP requires significant memory for large graphs:
| Coverage Area | Recommended Memory |
|---|---|
| City | 2-4 GB |
| Metro Area | 4-8 GB |
| State/Region | 8-16 GB |
| Country | 16-32 GB |
Query Performance
- Pre-compute common routes if possible
- Use caching for repeated queries
- Consider geographic sharding for very large areas
- Monitor query latency and adjust resources
Troubleshooting Common Issues
Out of Memory Errors
Symptoms: OTP crashes during graph loading or routing.
Solutions:
- Increase JAVA_OPTS memory allocation
- Use a smaller geographic area
- Reduce the number of GTFS feeds
- Check for memory leaks in custom configurations
No Routes Found
Symptoms: API returns no itineraries.
Solutions:
- Verify transit data covers the requested time
- Check that origin/destination are within coverage area
- Ensure street network connects to transit stops
- Review GTFS calendar data for service dates
Graph Build Failures
Symptoms: Graph building crashes or hangs.
Solutions:
- Verify GTFS files are valid
- Ensure OSM data is not corrupted
- Check for sufficient disk space
- Review build logs for specific errors
Slow Query Performance
Symptoms: Routing requests take too long.
Solutions:
- Increase memory allocation
- Reduce graph complexity
- Implement query caching
- Scale horizontally for high traffic
Additional Resources
- OpenTripPlanner Official Website
- OpenTripPlanner Documentation
- OpenTripPlanner GitHub Repository
- GTFS Specification
- Geofabrik OSM Downloads
- Klutch.sh Persistent Volumes
- Klutch.sh Deployments
Conclusion
Deploying OpenTripPlanner on Klutch.sh provides a powerful multimodal trip planning service for your city or region. With support for transit, walking, cycling, and real-time updates, OTP enables sophisticated transportation applications.
The combination of persistent graph storage and scalable resources makes Klutch.sh well-suited for OTP deployment. Whether building a transit app, analyzing transportation accessibility, or providing journey planning for your organization, your self-hosted OpenTripPlanner instance delivers reliable routing services.
Start with a single city, expand to regional coverage, and integrate real-time feeds to provide up-to-the-minute trip planning for your users.