Get tileserver-rs running with real map data in just a few minutes.
Prerequisites
- Docker installed, OR
- tileserver-rs
Step 1: Download Sample Data
We'll use a sample PMTiles file containing OpenStreetMap data for Florence, Italy:
mkdir -p data/tiles
curl -L -o data/tiles/florence.pmtiles \
https://github.com/vinayakkulkarni/tileserver-rs/raw/main/data/tiles/protomaps-sample.pmtiles
Step 2: Start the Server
You can start the server with zero config (auto-detect) or with an explicit config file:
Zero-Config (auto-detect)
# Point at the data directory — sources, styles, and fonts are auto-detected
tileserver-rs data/
You should see:
INFO tileserver_rs: Auto-detected from: /path/to/data
INFO tileserver_rs: Sources: 1 (florence)
INFO tileserver_rs: Starting tileserver on http://0.0.0.0:8080
Info
Zero-config auto-detect finds .pmtiles, .mbtiles, style.json, fonts, and GeoJSON files. See the
Step 4: Explore Your Tiles
Open your browser to http://localhost:8080 to see the built-in map viewer.
Available Endpoints
| Endpoint | Description |
|---|---|
| localhost:8080 | Web UI with map viewer |
| localhost:8080/data.json | List all tile sources |
| localhost:8080/data/florence.json | TileJSON metadata |
| localhost:8080/health | Health check |
| localhost:8080/ping | Runtime metadata (config hash, version) |
Fetch a Tile
# Get a vector tile (zoom 14, Florence city center)
curl -I http://localhost:8080/data/florence/14/8704/5972.pbf
# Response:
# HTTP/1.1 200 OK
# content-type: application/x-protobuf
# content-encoding: gzip
Step 5: Display in MapLibre GL JS
Create an index.html file:
<!DOCTYPE html>
<html>
<head>
<title>My First Tile Server</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.css"
rel="stylesheet"
/>
<script src="https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
const map = new maplibregl.Map({
container: 'map',
style: {
version: 8,
sources: {
florence: {
type: 'vector',
url: 'http://localhost:8080/data/florence.json',
},
},
layers: [
{
id: 'water',
type: 'fill',
source: 'florence',
'source-layer': 'water',
paint: { 'fill-color': '#a0cfdf' },
},
{
id: 'roads',
type: 'line',
source: 'florence',
'source-layer': 'transportation',
paint: { 'line-color': '#888', 'line-width': 1 },
},
{
id: 'buildings',
type: 'fill',
source: 'florence',
'source-layer': 'building',
paint: { 'fill-color': '#d9c9b9', 'fill-opacity': 0.7 },
},
],
},
center: [11.255, 43.77], // Florence, Italy
zoom: 14,
});
</script>
</body>
</html>
Open index.html in your browser to see the map!
What's Next?
Common Issues
Port Already in Use
# Use a different port
docker run -p 3000:8080 ...
# Or with local binary
tileserver-rs --config config.toml --port 3000
Permission Denied (Docker)
Make sure your data directory is readable:
chmod -R 755 data/
Tiles Return 404
Check that your source ID matches the URL path:
- Config:
id = "florence" - URL:
/data/florence/{z}/{x}/{y}.pbf