docker pull atcr.io/rtw.run/pmtiles:latest
pmtiles
Vector tile server for rtw.run, an adventure motorcycle trip planning app.
Serves a directory of PMTiles archives as /{archive}/{z}/{x}/{y}.mvt on port 9090. If the /data volume is empty it downloads the previous day’s Protomaps planet build (~137GB, no API key) from build.protomaps.com and exposes it as https://tiles.rtw.run/world/{z}/{x}/{y}.mvt via a world.pmtiles symlink. Drop your own archives (e.g. india-nepal.pmtiles) into /data and they are served at /india-nepal/{z}/{x}/{y}.mvt instead — the world is only downloaded when the directory is empty.
Running the container
Multiarch image (amd64 + arm64): atcr.io/rtw.run/pmtiles:latest
mkdir -p /srv/rtw/pmtiles
podman run -d --name pmtiles --userns=keep-id \
-p 127.0.0.1:9090:9090 \
-v /srv/rtw/pmtiles:/data \
atcr.io/rtw.run/pmtiles:latest
Keep >= 300GB free on the volume (the planet build is ~137GB and is replaced on refresh).
| Var | Default | Meaning |
|---|---|---|
PORT |
9090 |
HTTP port |
CORS |
http://localhost:5173,https://rtw.run,https://next.rtw.run |
Allowed origins for the Access-Control-Allow-Origin header |
CACHE_SIZE |
128 |
Header/directory LRU cache size in MB |
PUBLIC_URL |
https://tiles.rtw.run |
Public base URL used for TileJSON |
podman kill -s HUP pmtiles refreshes the planet: it downloads the newest daily build, atomically re-points world.pmtiles, restarts the server, and deletes the stale build. The server is ready as soon as it starts (tiles are read lazily) — health check: curl -fsS http://localhost:9090/world.json.
Source: go-pmtiles · Basemap: https://docs.protomaps.com/basemaps/downloads