Offline tiles were built from Protomaps' own basemap schema, needing a completely separate hand-tuned theme (protomaps-themes-base + OFFLINE_THEME) from the online Liberty style's ONLINE_STYLE_PATCH — the two could never be made to match exactly no matter how much either side got tuned (today's session found and fixed several mismatches: building opacity, park boundaries, road casings, road widths). Offline.pmtiles is now built with Planetiler's default OpenMapTiles profile against Geofabrik per-country OSM extracts (osmium-merged when more than one country is selected), the same vector schema Liberty already expects. offlineStyle() now clones the same Liberty JSON (vendored as a local snapshot for reliability with no internet) and applies the identical ONLINE_STYLE_PATCH, just repointed at local PMTiles/glyphs/sprite — one palette instead of two, correct on both sides by construction. Also vendors Liberty's icon sprite for the first time (offline had none before), adds Java/osmium-tool/planetiler.jar to the Docker image, and removes the now-unused protomaps-themes-base dependency and the theme-comparison debug page that found today's bugs.
122 lines
7.0 KiB
YAML
122 lines
7.0 KiB
YAML
services:
|
|
maptool:
|
|
# "./build", not ".": the compose file's own context ("." would mean
|
|
# the symlink's directory, /srv/podman/maptool/ — see docs/deployment.adoc)
|
|
# is one level above where the actual checkout (and its Dockerfile)
|
|
# lives since the previous commit moved it into build/. Volume paths
|
|
# below resolve against that same symlink directory too, but a relative
|
|
# *build context* specifically needs pointing at build/ itself — the
|
|
# gap this fixes: production's compose up --build failed outright
|
|
# ("lstat .../maptool/Dockerfile: no such file or directory") until this
|
|
# was caught, since only the volume-path resolution got dry-run tested
|
|
# before the previous commit shipped, not this one.
|
|
build: ./build
|
|
image: maptool:latest
|
|
restart: unless-stopped
|
|
ports:
|
|
- "4567:4567"
|
|
environment:
|
|
# "[::]", not "0.0.0.0": binding the IPv6 wildcard also accepts IPv4
|
|
# connections (dual-stack is the Linux default), so this covers both
|
|
# without a second listener. Puma's bind URL needs the brackets around
|
|
# a literal IPv6 address (config/puma.rb interpolates this as-is).
|
|
BIND_HOST: "[::]"
|
|
RACK_ENV: production
|
|
# Read from .env (docker compose loads it automatically) — not
|
|
# committed, see docs/deployment.adoc.
|
|
SESSION_SECRET: ${SESSION_SECRET:?SESSION_SECRET is required, see docs/deployment.adoc}
|
|
GITEA_OAUTH_CLIENT_ID: ${GITEA_OAUTH_CLIENT_ID:?GITEA_OAUTH_CLIENT_ID is required, see docs/deployment.adoc}
|
|
GITEA_OAUTH_CLIENT_SECRET: ${GITEA_OAUTH_CLIENT_SECRET:?GITEA_OAUTH_CLIENT_SECRET is required, see docs/deployment.adoc}
|
|
MAPTOOL_ALLOWED_GITEA_USER: ${MAPTOOL_ALLOWED_GITEA_USER:?MAPTOOL_ALLOWED_GITEA_USER is required, see docs/deployment.adoc}
|
|
# Optional: blank disables the LiveTrack webhook endpoint rather than
|
|
# failing to start, since it's not needed for the app's core function.
|
|
LIVETRACK_WEBHOOK_SECRET: ${LIVETRACK_WEBHOOK_SECRET:-}
|
|
# Optional, only read by data/plugins/p4n2gpx/'s own p4n2gpx.rb (not
|
|
# part of this repo — see docs/deployment.adoc) if that private
|
|
# plugin is present; blank just means it fails with its own "could
|
|
# not authenticate" error when run, same non-fatal-to-startup story
|
|
# as the other optional secrets here. P4N_USER/P4N_PASSWORD alone
|
|
# don't actually work here — park4night's login form is behind
|
|
# invisible reCAPTCHA, which no browserless login can satisfy — so
|
|
# P4N_SESSION_COOKIE (a real logged-in browser's session cookie,
|
|
# copied out by hand and refreshed whenever it expires) is what
|
|
# p4n2gpx.rb's make_session actually ends up using.
|
|
P4N_USER: ${P4N_USER:-}
|
|
P4N_PASSWORD: ${P4N_PASSWORD:-}
|
|
P4N_SESSION_COOKIE: ${P4N_SESSION_COOKIE:-}
|
|
# The kiwix service below, reached by its compose service name (both
|
|
# are on the same default compose network) — port matches its own
|
|
# --port=8080 in the command below. Not made conditional on the ZIM
|
|
# actually being present: GET /api/kiwix pings it and just reports
|
|
# unavailable if the container isn't up/reachable, same story as
|
|
# every other optional-local-file feature (offline.pmtiles, etc).
|
|
# Reached server-side only — production sits behind a reverse proxy
|
|
# that only forwards to maptool itself, so app.rb's GET /kiwix/*
|
|
# proxies to this instead of handing the browser this address.
|
|
KIWIX_URL: "http://kiwix:8080"
|
|
volumes:
|
|
# Uploaded GPX files and the offline PMTiles extract — kept outside
|
|
# the image so a rebuild/redeploy doesn't wipe them (see
|
|
# docs/development.adoc for how the deploy job treats this
|
|
# directory). A private plugin (app.rb's PLUGINS_DIRS) also belongs
|
|
# under here, at data/plugins/<name>/ — nothing further to mount,
|
|
# this one bind already covers the whole data/ tree. An offline.pmtiles
|
|
# build's own scratch work (Dir.mktmpdir, lib/maptool/pmtiles_builder.rb)
|
|
# happens outside this mount, in the container's own filesystem — a
|
|
# large country's .osm.pbf plus Planetiler's working set can be
|
|
# several GB, worth knowing if the host is ever short on space there.
|
|
- ./data:/app/data
|
|
|
|
# Fakes a GNSS fix (a loop around Bratislava, see
|
|
# bin/gnss_simulator.rb/docs/development.adoc) since there's no real
|
|
# receiver attached here — the "GNSS" control would otherwise just show
|
|
# "no fix" always. Remove this service (and nothing else) whenever a real
|
|
# receiver/gpsd setup replaces it. network_mode ties it to maptool's own
|
|
# network namespace rather than a bridge network, since GpsdClient
|
|
# connects to a hardcoded 127.0.0.1:2947 — same as gpsd itself normally
|
|
# being local to the machine it serves.
|
|
gnss-simulator:
|
|
image: maptool:latest
|
|
depends_on:
|
|
- maptool
|
|
restart: unless-stopped
|
|
network_mode: "service:maptool"
|
|
command: ["ruby", "bin/gnss_simulator.rb"]
|
|
|
|
# Serves an offline Wikipedia ZIM for the popup's "Nearby on Wikipedia"
|
|
# link (see docs/development.adoc for where to get one and drop it in —
|
|
# same "not part of the repo, place it under ./data locally" story as
|
|
# offline.pmtiles/terrain.pmtiles). On the default compose network (not
|
|
# network_mode: "service:maptool" — unlike gnss-simulator this doesn't
|
|
# need a hardcoded localhost port, KIWIX_URL above reaches it by this
|
|
# service's own name), so maptool and kiwix stay independent containers.
|
|
# Keeps restarting (harmlessly) if data/kiwix/wikipedia.zim isn't there
|
|
# yet — GET /api/kiwix just reports unavailable until it comes up.
|
|
#
|
|
# The volume binds the exact *file* path, not the data/kiwix/ directory —
|
|
# deliberately, so data/kiwix/wikipedia.zim can be a symlink to wherever
|
|
# the (large) real ZIM actually lives. A bind mount resolves a symlink at
|
|
# its *source* path once, at mount time (plain mount(2) semantics, same
|
|
# as Podman); a symlink sitting inside an already-mounted directory
|
|
# doesn't get that treatment — the container would have to resolve it
|
|
# itself, inside its own filesystem, where the host path it points to
|
|
# doesn't exist.
|
|
kiwix:
|
|
image: ghcr.io/kiwix/kiwix-serve:latest
|
|
restart: unless-stopped
|
|
# No --port here: the image's own start.sh already prepends
|
|
# --port=8080 (its default) before appending this command array, so
|
|
# passing it again produced "Unexpected argument: --port=8080,
|
|
# --port=8080, /data/wikipedia.zim" and kiwix-serve refused to start.
|
|
#
|
|
# --urlRootLocation=/kiwix makes every link/asset kiwix-serve itself
|
|
# emits (search results, article pages, its CSS/JS) carry a /kiwix
|
|
# prefix, matching where app.rb's GET /kiwix/* proxies requests in
|
|
# from (confirmed against libkiwix's internalServer.cpp: it strips
|
|
# this same prefix off incoming request paths, so both ends agree on
|
|
# it) — no ports: mapping needed, nothing outside the compose network
|
|
# ever talks to this container directly.
|
|
command: ["--urlRootLocation=/kiwix", "/data/wikipedia.zim"]
|
|
volumes:
|
|
- ./data/kiwix/wikipedia.zim:/data/wikipedia.zim
|