Docs Getting started

neoserver 0.1.2

Publish with the API

Initialize neoserver, connect PostGIS, and publish an authenticated OGC service using HTTP.

Use the neoserver checkout. The commands in this guide run from the root of tobilg/neoserver, not the website repository. Clone the project and check out v0.1.2 before starting.

This tutorial starts neoserver with Docker Compose, connects it to the repository’s seeded PostGIS database, publishes two layers, enables WMS and WFS, and verifies the resulting services.

Prefer the browser? The separate UI-first tutorial covers sign-in, workspace creation, PostGIS connection or file upload, publication, preview and client access without management API commands. For contributing code, use make dev.

Prerequisites

  • Docker with Compose support
  • curl
  • jq
  • OpenSSL
  • Ports 9000 and 5432 available

Run all commands from the repository root.

1. Initialize the encrypted store

Set the local development encryption key and public server URL:

export NEOSRV_STORE_KEY=abc123 # Local tutorial only; generate a strong key for deployment.
export NEOSRV_SERVER_URLBASE="http://localhost:9000"

Keep NEOSRV_STORE_KEY safe. The same value is required whenever the store is opened, and it cannot be changed after initialization. For any non-local deployment, generate a key with openssl rand -hex 32; never use the example key. The key encrypts the catalog, it is not a sign-in token.

Initialize the store:

docker compose build server
docker compose run --rm --no-deps server init --store-path /data/neoserver.db

The command prints a super_admin bootstrap token that expires after 24 hours. Copy it into your shell:

export TOKEN="paste-bootstrap-token-here"

If the token expires, stop the server (the catalog has a single writer) and create another one with the same store and encryption key, then restart:

docker compose stop server
docker compose run --rm --no-deps server create-token \
  --store-path /data/neoserver.db \
  --role super_admin \
  --expires 24h
docker compose --profile postgis up -d

2. Start neoserver and PostGIS

The PostGIS service uses a Compose profile, so include it explicitly:

docker compose --profile postgis up --build

Run the remaining commands in another terminal with NEOSRV_STORE_KEY, NEOSRV_SERVER_URLBASE, and TOKEN exported.

Check readiness:

curl -fsS http://localhost:9000/ready | jq

Expected response:

{
  "status": "ready",
  "checks": {
    "catalog": "ok",
    "catalog_lifecycle": "ok",
    "mosaic_catalog": "disabled",
    "tile_cache": "disabled",
    "tile_cache_lease": "disabled",
    "tile_jobs": "disabled"
  }
}

3. Create a workspace

Workspaces isolate data connections, published layers, styles, service settings, and access control.

curl -fsS -X POST http://localhost:9000/api/v1/workspaces \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "demo",
    "description": "Getting started workspace"
  }' | jq

Management routes accept a workspace name or UUID. The public service URLs use the workspace name.

4. Connect the seeded PostGIS database

From the server container, the database host is db rather than localhost. The connection field is named user.

curl -fsS -X POST \
  http://localhost:9000/api/v1/workspaces/demo/services \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "sample-postgis",
    "type": "postgis",
    "connection_info": {
      "host": "db",
      "port": 5432,
      "database": "postgis",
      "user": "postgres",
      "password": "postgres",
      "sslmode": "disable",
      "schemas": ["public"]
    }
  }' | jq

Credentials in this example are for local development only.

5. Discover and publish layers

Discover the source tables:

curl -fsS -X POST \
  http://localhost:9000/api/v1/workspaces/demo/services/sample-postgis/discover \
  -H "Authorization: Bearer $TOKEN" | jq

Publish the seeded point and polygon tables:

curl -fsS -X POST \
  http://localhost:9000/api/v1/workspaces/demo/services/sample-postgis/layers \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "source_layer": "public.places",
    "public_id": "places",
    "title": "Places"
  }' | jq

curl -fsS -X POST \
  http://localhost:9000/api/v1/workspaces/demo/services/sample-postgis/layers \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "source_layer": "public.areas",
    "public_id": "areas",
    "title": "Areas"
  }' | jq

OGC API - Features is enabled for new workspaces. WMS and WFS must be enabled per workspace as well as globally; the Compose service enables them globally.

6. Enable WMS and WFS

curl -fsS -X PUT \
  http://localhost:9000/api/v1/workspaces/demo/settings/wms \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "title": "Demo WMS",
    "max_width": 4096,
    "max_height": 4096
  }' | jq

curl -fsS -X PUT \
  http://localhost:9000/api/v1/workspaces/demo/settings/wfs \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "title": "Demo WFS",
    "max_features": 10000
  }' | jq

7. Query the services

List collections and fetch features:

curl -fsS -H "Authorization: Bearer $TOKEN" \
  http://localhost:9000/workspaces/demo/ogc/collections | jq

curl -fsS -H "Authorization: Bearer $TOKEN" \
  "http://localhost:9000/workspaces/demo/ogc/collections/places/items?limit=2" | jq

Request WMS and WFS capabilities:

curl -fsS -H "Authorization: Bearer $TOKEN" \
  "http://localhost:9000/workspaces/demo/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities"

curl -fsS -H "Authorization: Bearer $TOKEN" \
  "http://localhost:9000/workspaces/demo/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetCapabilities"

Open the administration console at http://localhost:9000/admin/ and choose the demo workspace. Its Preview page provides the interactive map.

8. Create an application API key

Self-signed JWTs are intended primarily for bootstrap and recovery. Create a workspace API key for a client:

curl -fsS -X POST \
  http://localhost:9000/api/v1/workspaces/demo/apikeys \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "demo-client",
    "owner_name": "Getting Started",
    "role_id": "viewer"
  }' | jq

The full key is returned only once. Use it with X-API-Key:

# Bash: paste the viewer secret without recording it in shell history.
read -r -s NEOSRV_API_KEY
export NEOSRV_API_KEY
printf '\n'
curl -fsS -H "X-API-Key: $NEOSRV_API_KEY" \
  http://localhost:9000/workspaces/demo/ogc/collections

Stop and restart

Stop services without deleting persistent data:

docker compose --profile postgis down

On the next start, export the same NEOSRV_STORE_KEY and NEOSRV_SERVER_URLBASE, then run the compose up command. Do not run init again for an existing store.

Both the encrypted catalog (serverdata) and PostGIS (pgdata) use named Docker volumes. docker compose --profile postgis down -v deletes both, including imported files stored with the catalog. This is destructive, not a restart step; back up first and use it only if you explicitly want to discard the whole local environment.

Next steps

Adapted from neoserver’s source documentation . Maintained independently for this website.

Search documentation

Type to search guides and reference pages.