Github|...

Self-hosting

Run the scheduler and SSP yourself, single node or distributed, with the environment variables each needs.

Deploying Sp00ky requires running the Sp00ky Sidecar (SSP) alongside your SurrealDB instance. For production deployments, the Scheduler coordinates multiple SSP instances.

Architecture

  1. SurrealDB: Your persistent data store.
  2. Sp00ky SSP (Sidecar): A backend service that monitors SurrealDB for changes and maintains materialized views.
  3. Scheduler (optional): Central coordinator for distributed deployments with multiple SSPs. Maintains a RocksDB snapshot replica and WAL.
  4. Client: Connects directly to SurrealDB.

Single Node (Development)

The simplest setup for development and testing. No scheduler needed.

services:
  surrealdb:
    image: surrealdb/surrealdb:v3.1.0-beta.3
    command: start --user root --pass root rocksdb:/data/db
    ports:
      - "8666:8000"
    volumes:
      - ./data:/data

  ssp:
    image: ghcr.io/sp00ky-org/ssp-server:canary
    environment:
      - SPKY_DB_WS=ws://surrealdb:8000
      - SPKY_DB_USER=root
      - SPKY_DB_PASS=root
      - SPKY_DB_NS=main
      - SPKY_DB_NAME=app
      - SPKY_SSP_LISTEN_ADDR=0.0.0.0:8667
      - SPKY_AUTH_SECRET=your-secret-token
      - SPKY_SSP_REF_MODE=dedicated
    ports:
      - "8667:8667"
    depends_on:
      - surrealdb

Distributed (Production)

For production with high availability and horizontal scaling, use a Scheduler with multiple SSP instances.

services:
  surrealdb:
    image: surrealdb/surrealdb:v3.1.0-beta.3
    command: start --user root --pass root rocksdb:/data/db
    ports:
      - "8666:8000"
    volumes:
      - surreal-data:/data

  scheduler:
    image: ghcr.io/sp00ky-org/scheduler:canary
    environment:
      - SPKY_DB_WS=ws://surrealdb:8000
      - SPKY_DB_NS=main
      - SPKY_DB_NAME=app
      - SPKY_DB_USER=root
      - SPKY_DB_PASS=root
      - SPKY_SCHEDULER_ID=scheduler-01
      - SPKY_AUTH_SECRET=your-secret-token
    # Bind host/port and storage paths come from the scheduler's
    # sp00ky.yml (ingest_host, ingest_port, replica_db_path, wal_path).
    ports:
      - "9667:9667"
    volumes:
      - scheduler-data:/app/data
    depends_on:
      - surrealdb

  ssp-1:
    image: ghcr.io/sp00ky-org/ssp-server:canary
    environment:
      - SPKY_SSP_ID=ssp-01
      - SPKY_DB_WS=ws://surrealdb:8000
      - SPKY_DB_USER=root
      - SPKY_DB_PASS=root
      - SPKY_DB_NS=main
      - SPKY_DB_NAME=app
      - SPKY_SSP_LISTEN_ADDR=0.0.0.0:8667
      - SPKY_AUTH_SECRET=your-secret-token
      - SPKY_SCHEDULER_URL=http://scheduler:9667
      - SPKY_SSP_ADVERTISE_ADDR=ssp-1:8667
      - SPKY_SSP_REF_MODE=dedicated
      - HEARTBEAT_INTERVAL_MS=5000
    ports:
      - "8667:8667"
    depends_on:
      - surrealdb
      - scheduler

  ssp-2:
    image: ghcr.io/sp00ky-org/ssp-server:canary
    environment:
      - SPKY_SSP_ID=ssp-02
      - SPKY_DB_WS=ws://surrealdb:8000
      - SPKY_DB_USER=root
      - SPKY_DB_PASS=root
      - SPKY_DB_NS=main
      - SPKY_DB_NAME=app
      - SPKY_SSP_LISTEN_ADDR=0.0.0.0:8667
      - SPKY_AUTH_SECRET=your-secret-token
      - SPKY_SCHEDULER_URL=http://scheduler:9667
      - SPKY_SSP_ADVERTISE_ADDR=ssp-2:8667
      - SPKY_SSP_REF_MODE=dedicated
      - HEARTBEAT_INTERVAL_MS=5000
    ports:
      - "8668:8667"
    depends_on:
      - surrealdb
      - scheduler

volumes:
  surreal-data:
  scheduler-data:

Environment Variables

SSP (Sidecar)

All SPKY_* vars below are read directly from the process environment.

VariableDescriptionDefault
SPKY_SSP_LISTEN_ADDRAddress and port for the SSP HTTP server0.0.0.0:8667
SPKY_AUTH_SECRETBearer token for authenticating SSP API requests. When unset the auth middleware accepts any bearer (dev only).(empty)
SPKY_DB_URLSurrealDB URL (HTTP engine; ws:// values are accepted and normalized)http://127.0.0.1:8000
SPKY_DB_WSLegacy fallback for SPKY_DB_URL (any scheme accepted)(unset)
SPKY_DB_USERSurrealDB usernameroot
SPKY_DB_PASSSurrealDB passwordroot
SPKY_DB_NSSurrealDB namespacetest
SPKY_DB_NAMESurrealDB databasetest
SPKY_SCHEDULER_URLScheduler URL (enables distributed mode)(unset)
SPKY_SSP_IDUnique SSP identifierssp-<uuid>
SPKY_SSP_ADVERTISE_ADDRExternally reachable host:port for this SSP(unset)
HEARTBEAT_INTERVAL_MSHeartbeat interval in ms5000
TTL_CLEANUP_INTERVAL_SECSView TTL cleanup interval60
SPKY_SSP_REF_MODE_00_list_ref storage layout: dedicated (per-user tables; works around the SurrealDB v3 LIVE permission gap) or single (legacy shared table). Mirrors refMode in sp00ky.yml.dedicated
SPKY_SSP_QUERY_UPDATE_THROTTLE_MSWindow (ms) over which the SSP coalesces query edge-update writes to _00_list_ref into one batched transaction, so a burst of view updates lands as a few batched LIVE deliveries instead of one transaction per record. 0 disables batching (flush each update immediately). See Architecture.100
SPKY_JOB_CONFIGJSON-encoded { "job_tables": { … } } describing backends the SSP can dispatch to.(unset)
SPKY_CRDT_CACHE_SIZEIn-memory CRDT cache capacity10000
SPKY_CRDT_FIELDSJSON override for @crdt field detection, e.g. {"thread":["content"]}(auto)
SPKY_SSP_BOOTSTRAP_PAGE_SIZERows pulled per /proxy/query page500
OTEL_EXPORTER_OTLP_ENDPOINTOpenTelemetry collector endpoint for SSP metrics(unset)
OTEL_SERVICE_NAMEOTEL service identifierssp

Scheduler

The scheduler reads most of its config from sp00ky.yml. The SPKY_* env vars below override the corresponding YAML field. Every other field (ingest_host, ingest_port, load_balance, heartbeat_*, bootstrap_*, replica_db_path, wal_path, ssp_poll_interval_ms, max_buffer_per_ssp, job_tables) is YAML only.

VariableDescriptionDefault
SPKY_SCHEDULER_IDUnique scheduler identifierscheduler-<uuid>
SPKY_DB_URLSurrealDB URL (HTTP engine; ws:// values are accepted and normalized)http://localhost:8000
SPKY_DB_WSLegacy fallback for SPKY_DB_URL (any scheme accepted)(unset)
SPKY_DB_NSSurrealDB namespacesp00ky
SPKY_DB_NAMESurrealDB databasesp00ky
SPKY_DB_USERSurrealDB usernameroot
SPKY_DB_PASSSurrealDB passwordroot
SPKY_SNAPSHOT_UPDATE_INTERVAL_SECSSnapshot update interval (seconds)300
SPKY_BOOTSTRAP_PAGE_SIZERows read per bootstrap page from the replica500
SPKY_AUTH_SECRETOptional shared secret; when set, callers to /proxy/* must send Authorization: Bearer <secret>.(empty)
SPKY_BACKENDSJSON-encoded backend health-check list (SPKY_SCHEDULER_BACKENDS accepted as legacy fallback)(unset)