Skip to content

Deployment

Two long-running containers and one batch job:

Service What it does When it runs Port (default)
viewer Web app and server: lists the layers in the data directory, builds tiles (tippecanoe), saves styles; configured by viewer/viewer.yaml Permanently 127.0.0.1:8080
docs This documentation site; built at start from docs/ and the layers in the data directory, served by nginx Permanently 127.0.0.1:8081
openwater Runs a layer script: downloads OSM data (cached), exports layer packages into the data directory Batch job (profile batch) –

They share the data directory (VIEWER_DATA_DIR, default ./data/viewer) and nothing else. openwater writes the projects (projects/<id>.json), layer.json and data.geojson; the viewer writes style.json and tiles.pmtiles; the docs only read. The download cache is ./data/cache. See Architecture.

The map and the docs link to each other: the Docs button on the map, and Open the map in the docs. The browser follows these links, so they must be the public URLs:

Variable Used by Applied
DOCS_URL viewer: Docs button and rule "Details" links at container start
MAP_URL docs: "Open the map" link at container start (the site is built then)

Local development

cp .env.example .env
make build          # build all images (the first build compiles tippecanoe, about 5 min)
make layers         # run all layer scripts in layers/ → data/viewer/layers/
make dev            # map: http://127.0.0.1:8080 · docs: http://127.0.0.1:8081

The viewer is editable with make dev and read-only with make up (unless VIEWER_READ_ONLY is set).

Target Does
make check Check the layer definitions in all scripts (no download)
make test openwater tests
make layers Run all layer scripts; SCRIPTS=layers/kiel.py for one, ARGS=--refresh to download again, ARGS="--only kiel-hydrants" for one layer
make dev / make up / make down Start (development / production) or stop viewer and docs
make tiles Build the tiles of all layers now instead of on the first request

On the server, ./server.sh replaces make (bash and Docker Compose only), see Production deployment.

make dev uses compose.dev.yaml: - Viewer: viewer/web/src/ and viewer/server/ are mounted; the server reloads on changes, the web app after a browser reload. - Docs: mkdocs serve with live reload, including newly exported layers. Changes to docs-server/ need make build. - openwater: openwater/src/ is mounted; layer scripts are always mounted from layers/.

The first make layers downloads the Zensus grid (19 MB) and the GTFS timetable for Germany (270 MB) into data/cache/downloads/, and counts departures once (about a minute); later runs use the cache. ARGS=--refresh downloads everything again.

openwater also works without Docker: pip install -e openwater, then python layers/kiel.py (see Writing layers).

Server

See Production deployment: configuration, reverse proxy (Caddy, nginx), checks, scheduled data updates, backups and troubleshooting.

Third-party requests

The map libraries (MapLibre, PMTiles) and the docs libraries (Material theme, Mermaid) are served from the containers; the docs site loads no external fonts. Only the map's basemap is loaded from a third party (by default OpenFreeMap), so viewers' IP addresses go to that tile server. For a public German deployment, either mention this in the privacy notice or self-host a basemap. Set the default in viewer/viewer.yaml → basemap.default, e.g. to a self-hosted vector style.

Users can switch the basemap themselves in Settings → Background map (a raster tile URL or a vector style URL). Their choice is stored in their browser (localStorage) and only affects their own view.

Versions

Component Version Where pinned
MapLibre GL JS 6.14.0 viewer/web/package.json
PMTiles JS 4.5.0 viewer/web/package.json
tippecanoe 2.79.0 viewer/Dockerfile
Starlette / uvicorn 1.10.0 / 0.54.0 viewer/server/requirements.txt
MkDocs / Material 1.6.1 / 9.8.0 docs-server/requirements.txt
Mermaid (docs) 11.17.2 docs-server/Dockerfile

Material for MkDocs is in maintenance mode, and the same team now builds Zensical, which reads the same mkdocs.yml. The pinned versions keep working; migrating is an option once Zensical is stable.