Skip to content

maputnik

Version 2026.144.1443
Repo superproject

Visual MapLibre GL style editor (Maputnik SPA) built from upstream source and served as a static dist over HTTP on port 8000 Clones the upstream maplibre/maputnik repo at image-build time, runs npm ci + npm run build -- --base=/, and copies Vite’s emitted dist/ to /opt/maputnik/build/. The –base=/ override keeps asset URLs root-relative so they resolve under the serve path instead of 404ing at /maputnik/assets/*. The stdlib python3 -m http.server 8000 --directory /opt/maputnik/build runs as the always-restart maputnik service. It pairs with the osm-tools martin tile server (the editor at :8000 points at the tile catalog at :3000). Every fact below is observable: the built SPA dist + index.html, the node build toolchain, the running service, the HTTP 200 the editor returns, and the absence of the /maputnik/ asset prefix in the served HTML.

  • maputnik

This candy’s plan: — the runnable spec charly check executes against a live deployment. check: steps are idempotent probes; run: steps change state.

Intent Step
run mkdir=/opt/maputnik
run command=set -euo pipefail # Clone shallow + most recent tag’s tip. The maputnik repo has no # binary releases on GitHub — source build is the canonical install. git clone –depth 1 https://github.com/maplibre/maputnik /tmp/maputnik cd /tmp/maputnik # npm ci over npm install because lockfile is upstream-provided # and we want deterministic resolution. –no-audit + –no-fund cut # ~5 sec of network chatter that only spams stderr. npm ci –no-audit –no-fund # Maputnik’s package.json "build": "tsc && vite build" runs # vite with its default --base=/maputnik/, which bakes # /maputnik/assets/* references into the emitted HTML. We # serve the static dist at / via python -m http.server, so # those baked paths 404 in the browser. Override base to / # so asset URLs are root-relative and resolve against our # serve path. The -- forwards the flag through npm to vite. npm run build – –base=/ # Maputnik uses Vite (tsc && vite build --mode=production); Vite # default output is dist/, NOT build/ (the source-tree build/ # is just release scripts). Copy the actual SPA artifact and # error loudly if the layout changes upstream. if [ -d dist ]; then mkdir -p /opt/maputnik cp -r dist /opt/maputnik/build else echo “maputnik build did not produce ./dist directory” >&2 ls -la exit 1 fi cd / rm -rf /tmp/maputnik # Drop npm cache to shrink image (~150-300 MB delta). rm -rf /root/.npm
check the maputnik static dist directory was built from upstream source
check the SPA entrypoint index.html is present in the served dist
check the node runtime used to build the SPA is installed and runnable
check the maputnik service is running under the init system
check the static SPA answers HTTP 200 at the container root on the published port
check the served HTML carries no /maputnik/ asset prefix, so asset URLs resolve at the serve root
agent-check the loaded SPA presents the Maputnik visual style editor interface (layer list and map canvas), not a blank page
check addr=127.0.0.1:${HOST_PORT:8000}