Overview¶
Developer documentation for qgis-publish-service, a Go HTTP application that publishes QGIS projects, serves the browser UI, proxies QGIS Server, and integrates with Central authentication, GeoVault, OSRM, and the bundled qcarta-tiles cache.
Purpose¶
Provide a platform service for publishing and updating QGIS projects, exposing WMS/WFS through QGIS Server or CGI, managing project metadata and ACL registration, editing PostGIS features through generated forms, and importing operational GeoPackages into dedicated runtime PostGIS databases.
Major Features¶
- Upload, update, version, restore, and download
.qgs,.qgz, and supported ZIP project bundles. - Generate raster projects through Python/PyQGIS.
- Proxy WMS/WFS to QGIS Server or execute a local
qgis_mapserv.fcgi. - Extract forms, relations, legends, reports, layer metadata, and viewer configuration.
- Manage browser maps, thumbnails, basemaps, project metadata, and ingest sessions.
- Import GeoPackages into dedicated PostGIS databases with GDAL/OGR.
- Integrate with Central sessions and group/resource ACLs.
- Proxy GeoVault, OSRM, and the bundled qcarta tile/cache service.
Architecture Summary¶
The process is a single Go net/http server. Projects live on the filesystem under PROJECTS_ROOT. Optional Central PostgreSQL supplies sessions, ACLs, and service-owned registries (basemaps, browser maps, ingest sessions, project metadata, runtime datasets). Rendering uses QGIS Server either over HTTP or via local CGI. Cached tile/WMS traffic is reverse-proxied to qcarta-tiles. See Architecture.
flowchart LR
Client[Browser / CLI / API client] --> Publish[qgis-publish-service]
Publish --> Disk[(PROJECTS_ROOT)]
Publish --> PG[(Central / PostGIS)]
Publish --> QGIS[QGIS Server / CGI]
Publish --> Qcarta[qcarta-tiles]
Publish --> GeoVault[GeoVault]
Publish --> OSRM[OSRM]
Technology Stack¶
| Layer | Technology |
|---|---|
| Main service | Go 1.23, net/http, lib/pq, monorepo shared |
| Tile/cache service | Go 1.25 module under qcarta-tiles/ |
| Auth/ACL | Central PostgreSQL tables via shared/auth |
| GIS | QGIS Server, PyQGIS, GDAL/OGR (gdalinfo, ogrinfo, ogr2ogr) |
| UI | Static HTML/CSS/JS (OpenLayers, Materialize; no npm build) |
| CLI | Sibling acugis Python Typer CLI (../cli) |
| Deployment samples | systemd units; Apache/mod_fcgid examples for QGIS Server |
Repository Structure¶
| Path | Role |
|---|---|
cmd/server/ |
Main service entrypoint and route registration |
internal/ |
API handlers, publish pipeline, forms, stores, proxies |
html/qgis-publish/ |
Static management UI and viewer assets |
qcarta-tiles/ |
Independent tile/WMS cache service |
deploy/ |
systemd unit and environment sample |
apache/ |
QGIS Server / reverse-proxy examples |
scripts/, create-qgis-project.py |
PyQGIS raster project generation |
docs/ |
Developer documentation and OpenAPI |
Key Concepts¶
| Concept | Meaning |
|---|---|
| Project | Filesystem directory under PROJECTS_ROOT with a QGS and .qgis-publish.json |
| Render mode | direct, cache, or xyz — controls viewer/QGIS vs qcarta pathing |
| Service ACL | Central resource service / qgis_publish with view/edit/admin |
| Project ACL | Central resource qgis_project / <id>; new projects grant Public view by default |
| Runtime dataset | Isolated runtime_<slug> PostGIS database created from a GeoPackage import |
| Browser map | Map Builder document stored in PostgreSQL, independent of QGIS projects |
| BASE_PATH | Optional URL prefix for reverse-proxy mounts |
Typical Workflows¶
- Authenticate through Central (session cookie), then open the UI or call the API.
- Publish a project with
POST /projects/uploadoracugis maps publish. - View WMS through
/qgis/{id}or, in cache mode,/cache/...→ qcarta-tiles. - Edit PostGIS features through forms and feature create/update/delete endpoints.
- Import operational GeoPackages or use Add Data ingest/quick-import paths.
- Inspect versions, metadata, layers, and reports; restore a snapshot when needed.
Working client examples are in Examples. CLI mappings are in CLI.
Documentation¶
| Document | Contents |
|---|---|
| Installation | Requirements, build, local and production install |
| Configuration | Environment variables and config files |
| Architecture | Components, request flows, storage, workers |
| Database | Schemas, tables, pooling, initialization |
| Authentication | Sessions, ACLs, permissions, security notes |
| API | Every registered HTTP endpoint |
| OpenAPI | OpenAPI 3.1 machine-readable contract |
| Examples | curl, JavaScript, Python, Go, PHP workflows |
| CLI | acugis maps command mapping |
| Development | Tests, debugging, extension guidance |
| Deployment | systemd, reverse proxy, scaling, monitoring |
| Troubleshooting | Common failures and journal commands |
| Changelog | Keep a Changelog baseline starting at 1.0.0 |
| QGIS user context | Existing reference |
| QGIS expression support | Existing reference |
Verified support boundary¶
The repository contains systemd unit samples and an environment sample. It does not contain a Dockerfile, Compose file, Nginx configuration, TLS automation, CI workflow, packaging script, or release pipeline. Generic reverse-proxy and TLS guidance in Deployment is labeled as such and is not a claim of first-class repository packaging.
Security notice¶
Tracked environment, systemd, and application samples contain credential-like values. They are intentionally not reproduced here. Treat them as compromised examples: strip them from derived configuration, rotate corresponding credentials/tokens before production, and prefer a protected secret store or root-readable environment file.
Release status¶
Git contains no tags for this service. Commit history does not expose a reliable prior release series. The changelog therefore starts at 1.0.0 as a documentation baseline and does not assert that a corresponding artifact was previously published.