Files
map-asset-gateway/config/service.env.example
T
Harmon 73ad03fa59 Rewrite the gateway around health, retries, slicing and a Windows service
Scanner
- manifest lookup is now depth-bounded and prunes numeric zoom directories, so
  a scan no longer walks the whole tile payload
- rescans only report a version as updated when something actually changed
- overlapping runs are refused instead of interleaving their bookkeeping

Hot path
- token authorisation loads only that token grants and throttles the
  last_used_at write instead of touching it on every tile
- SQLite runs in WAL with a busy timeout and a real connection pool
- the catalog lookup used by /tiles no longer loads every basemap

Security
- the admin surface requires ADMIN_TOKEN (bearer) or ADMIN_USER/ADMIN_PASSWORD
  (basic), and the service refuses to bind off-host without credentials
- CORS is an explicit allow-list; newly minted tokens never reach a redirect URL
- client tokens are redacted from the access log

Operations
- resource health inspection flags a moved or deleted tile root before a 404
- pushes retry with backoff and can be re-queued by hand; the schedule lives in
  the database so a restart does not lose it
- access log plus /metrics counters

Image slicing
- tile_jobs drive the GDAL bundled with QGIS via scripts/gdal2tiles-qgis.bat
- layer_sources remembers what a layer is made of: submit one source to append
  a flight, or all of them to rebuild the layer as a VRT mosaic with no tile
  seams; the console exposes both, including a one-click rebuild
- slicing is available to integrations through a narrow slice token scope
  (submit, poll, idempotent by code, completion callback)

Console
- rebuilt around a fixed rail and single-view navigation with health and
  outstanding work leading, instead of one long scrolling page

Windows service
- native install/start/stop/status with crash recovery, auto-start and a
  rotating log file, so no NSSM wrapper is needed
- start-all.bat and stop-all.bat are removed: they killed the process by port
  with taskkill, which fought the service restart policy

Verified with 49 tests and live runs against real tile data and real GDAL.
2026-10-16 10:35:30 +08:00

68 lines
2.8 KiB
Bash

# Copy this file to config/service.env and adjust the machine-specific paths.
APP_ENV=dev
SERVICE_NAME=basemap-pusher
SERVICE_VERSION=0.2.0
SERVICE_COMMIT=local
API_HOST=127.0.0.1
API_PORT=8910
API_BASE_URL=http://127.0.0.1:8910
TILE_PUBLIC_BASE_URL=http://127.0.0.1:8910
VECTOR_PUBLIC_BASE_URL=http://127.0.0.1:8910
SQLITE_PATH=Z:\Code\tile-server\data\basemap-pusher.db
BASEMAP_SCAN_ROOT=Z:\Code\tile-server\data\tiles
VECTOR_SCAN_ROOT=Z:\Code\tile-server\data\geojson
AUTO_SCAN_ON_START=true
GOCACHE=Z:\Code\tile-server\.gocache
GOMODCACHE=Z:\Code\tile-server\.gomodcache
GOTMPDIR=Z:\Code\tile-server\.gotmp
GOPATH=Z:\Code\tile-server\.gopath
GOPROXY=https://goproxy.cn,direct
GOSUMDB=off
# --- Admin access ---------------------------------------------------------
# The admin console can mint tokens that read every basemap, so it must be
# protected whenever the service is reachable off-host. Binding to a non
# loopback API_HOST without credentials below makes startup fail on purpose.
#
# Browser console: set ADMIN_USER/ADMIN_PASSWORD (HTTP Basic).
# API clients: set ADMIN_TOKEN (Authorization: Bearer <token>).
# Leaving both empty is only allowed on 127.0.0.1 / ::1 / localhost.
#ADMIN_USER=ops
#ADMIN_PASSWORD=change-me
#ADMIN_TOKEN=change-me-too
# Comma-separated list of browser origins allowed to call the API. Empty means
# no cross-origin access at all; "*" allows every origin.
#CORS_ALLOWED_ORIGINS=https://maps.example.com
# Lifetime applied to newly created tokens when no explicit expiry is given.
# Use 0 to create tokens that never expire.
TOKEN_DEFAULT_TTL=720h
# --- Resource health & tile jobs -----------------------------------------
# How often catalogued paths are re-stat'ed so a moved/deleted resource is
# flagged before a client hits a 404. Use 0 to disable the periodic pass
# (the "立即巡检资源" button still works).
HEALTH_CHECK_INTERVAL=5m
# Command template that slices a raster into XYZ tiles. Placeholders:
# {input} {output} {zmin} {zmax} {tilesize} {format} {code}
# scripts/gdal2tiles-qgis.bat locates the GDAL bundled with QGIS (the Python
# bindings need the OSGeo4W environment, so a bare gdal2tiles.exe will not work).
TILE_JOB_COMMAND=D:\Code\tile-server\scripts\gdal2tiles-qgis.bat -p mercator -z {zmin}-{zmax} --xyz -w none --tilesize={tilesize} --exclude {input} {output}
# Where per-job stdout/stderr is written. Empty means <scan root>/.tile-jobs.
#TILE_JOB_LOG_DIR=
# Service tokens may carry the "slice" scope so an integration can submit tile
# jobs through POST /api/v1/slice/jobs without holding the admin credential.
# 多源镶嵌:提交多个源影像时,先用它拼成一张 VRT 再切片(逐像素拼接,
# 消除重叠区的瓦片接缝)。{inputs} 会展开成每个源各一个参数。
TILE_JOB_VRT_COMMAND=D:\Code\tile-server\scripts\gdalbuildvrt-qgis.bat -resolution highest {output_vrt} {inputs}