Every API, geoprocessing routine, analytic, and serving endpoint 3D Map Explorer runs on Windows also runs as a headless Linux service — shipped as .deb and .rpm packages, a Helm chart for Kubernetes, and Docker images. The ArcGIS Maps SDK viewer is not part of this build, which is exactly the point: bring your own renderer. Pair it with MapLibre GL Native on QNX or hardened Linux for vehicle, aircraft, and industrial deployments — or run it as pure back-end services with no map client at all.
This is not a stripped rewrite or a parallel codebase to keep in sync. The desktop application was always a thin native shell talking HTTP to an in-process server — so the headless build simply constructs that same host without the shell. Same engines, same routes, same contracts, built from the same commit.
:5059 exactly as they do on Windows. Existing clients need no changes.503 with an install hint instead of pretending to work.// the desktop build — unchanged native shell → LocalMapServerHost (in-process) net10.0-windows · DPAPI secrets // the headless build — same host, no shell Program.cs → LocalMapServerHost (console) net10.0 · linux-x64 · AES secrets ● identical engines ● identical REST + SSE routes on :5059 ✕ no desktop shell · no ArcGIS Maps SDK
Native packages for the two enterprise Linux families, a Helm chart for clusters, and container images for everything else — including an air-gapped variant with the full GDAL stack and pre-seeded extensions baked in.
Ubuntu / Debian amd64, self-contained — no .NET runtime to install first. Ships the hardened systemd unit and depends only on stock system libraries.
Built for the RHEL 9 family against Rocky Linux 9, staged from the same self-contained publish, with %config(noreplace) operator config and systemd preset integration.
A Kubernetes chart for the server workload — ConfigMap-driven settings, a persistent volume for on-disk state, health probes, and ingress with TLS terminated in front of a plain-HTTP pod.
A baseline linux-x64 image plus an air-gapped variant on a pinned full-GDAL base, with the DuckDB spatial extension pre-seeded so first run never reaches for the network.
Runs as an unprivileged mapexplorer system user under NoNewPrivileges, ProtectSystem=strict, ProtectHome and PrivateTmp, with a single writable data path.
Where Windows uses DPAPI, Linux encrypts the credential stores with AES-GCM keyed by a 32-byte file — mountable as a Kubernetes secret, backed up like any other key.
Packages install binaries under /opt/3dmapexplorer, operator configuration under /etc/3dmapexplorer, and durable data under /var/lib/3dmapexplorer — which package removal never deletes. The service is enabled but deliberately never auto-started, so an operator reviews the environment file before anything binds a port.
Because no viewer ships with this build, the server hosts yours. Drop a compiled web application into a watched folder and it is served at its own route — no rebuild of the server, no bundler step, no reverse proxy to configure. MapLibre, DeckGL, Cesium, TerriaJS, or anything else that compiles to static files.
# drop a built bundle in, it is served webapps/ ├─ fleet-maplibre/ → /apps/fleet-maplibre/ │ ├─ index.html │ ├─ assets/ style.json glyphs/ │ └─ tmg-app.json (optional manifest) ├─ terrain-cesium/ → /apps/terrain-cesium/ └─ ops-console/ → /apps/ops-console/ # the management surface GET /api/webapps GET /api/webapps/capabilities DELETE /api/webapps/{slug} ● no directory listing · root-contained
The server speaks open standards on the wire — vector tiles, OGC API Features, ArcGIS REST, imagery and elevation endpoints. Any client that reads those can be the renderer, which opens deployments the desktop build was never shaped for.
Run the services on the platform computer and render with MapLibre GL Native on a QNX or hardened-Linux head unit — a real-time-capable display stack fed by a full geospatial back end.
Mission computers that already have their own certified rendering path get imagery, terrain, features, and analytics from a service they can package, sign, and audit like any other.
Ruggedized gateways and control rooms where a Windows workstation is not an option, but OGC data services and on-device analytics still are.
No map client at all — schedule geoprocessing, publish tiles to an existing portal, or feed an analytics pipeline. The REST surface is the product.
Point the Windows desktop application at a remote headless server and it works unchanged — it was always an HTTP client.
QGIS and ArcGIS Pro connect to the same endpoints as ordinary services, so the server slots into a stack you already run.
Almost the entire processing core is pure C# over cross-platform natives, so it moves without compromise. The exceptions are the capabilities backed by Windows-only vendor libraries — and they are documented, not hidden.
| Capability | On Linux | Notes |
|---|---|---|
| Raster core — GeoTIFF / COG / JP2K | Full | Cross-platform GDAL natives |
| DuckDB spatial — MVT, FeatureServer, OGC API Features | Full | Pre-seed the extension for air-gapped hosts |
| Image classification — SAM, MaxLik, RF, SVM, XGBoost, K-means | Full | Pure C# plus the in-process tree walker |
| Stereo DSM, footprint & scene fusion | Full | Pure C# plus GDAL |
| SAR amplitude, dB conversion & speckle filtering | Full | Pure C# |
| ImageServer — exportImage, identify, mensuration | Full | Audited: zero Windows-native dependencies |
| AI detection sidecar | Full | Run the sidecar container alongside |
| SNAP / Snaphu / roofer / FFmpeg sidecars | Full | All ship Linux builds; swap the configured paths |
| Dashboard, job board & collects feed | Full | Vanilla JS, served by the host |
Esri mobile geodatabase — .geodatabase / .mmpk | 503 | Vendor library is Windows-only; no Linux build exists |
| LiDAR → I3S scene-layer package export | 503 | Encoders are Windows-only until built from source |
| Tradecraft GDAL formats — NITF / CADRG / CIB / RPF | 503 | Enabled by dropping in a full GDAL build — no code change |
Capability status reflects the platform's own Linux deployment matrix. Two of the three gaps are unlockable by supplying the relevant native builds at deploy time; the third depends on a proprietary library with no Linux distribution. Credentials encrypted on Windows with DPAPI are re-entered once during migration, after which they are readable on both platforms.
Every setting in the configuration file is overridable by environment variable, so one image serves a laptop container, a systemd host, and a cluster deployment without a bespoke build for each.
# install, then review before anything binds $ sudo apt install ./3dmapexplorer-server_*.deb $ sudoedit /etc/3dmapexplorer/server.env $ sudo systemctl start 3dmapexplorer # the hardening the unit ships with User=mapexplorer NoNewPrivileges=true ProtectSystem=strict ProtectHome=true PrivateTmp=true ReadWritePaths=/var/lib/3dmapexplorer ● data survives remove and purge
A desktop when you want the full workstation, a Linux service when you want the engine — packaged for the platform you actually deploy on, rendering with whatever draws your maps.