Github|...

Deploying

One command builds your images, provisions infrastructure, runs migrations and cuts over DNS.

Deploy

spky deploy

The deploy command performs these steps automatically:

  1. Validates your sp00ky.yml configuration
  2. Builds Docker images for each app (linux/amd64)
  3. Uploads images to Sp00ky Cloud (skips unchanged images)
  4. Provisions infrastructure (SurrealDB, Scheduler, SSP instances)
  5. Runs migrations against the cloud database
  6. Deploys your backend and frontend containers
  7. Configures DNS and SSL certificates

You’ll see real-time progress as each step completes.

Note

Run spky lint before deploying to catch config issues early.

Flags

FlagEffect
--upgradeAlso move the SSP and Scheduler to the newest published build. Only for a project whose version is any or unset: a pinned version stays where sp00ky.yml put it, and newest already rolls on every deploy.
--only api,webBuild and deploy just these apps. Everything else keeps running untouched.
--cleanWipe the scheduler’s persistent volume first. Last resort: the scheduler self-heals stale snapshot state on startup, and spky verify --fix (or POST /admin/resync on the scheduler) repairs it without a wipe. Your SurrealDB data is not touched either way.
--force-schemaRe-apply the internal schema and remote functions even when the hash says nothing changed. Drift recovery.
--cache-bustClients reloading onto this version clear service-worker caches first.
--mandatoryClients reload immediately instead of being offered a notification. Broken-build kill switch.
spky deploy --upgrade

--only is the one to reach for during normal iteration: a frontend-only change doesn’t need the backend rebuilt.

A backend on a dedicated machine shows up in the deploy table as machine/<name> with its public address, moving through creating, booting and serving. A deploy of such a backend takes a few minutes longer: a fresh VM boots beside the old one and only takes over once it answers its healthcheck.

Checking Status

spky status

Shows the current deployment version, status, and all running VMs with their roles and versions.

The operator dashboard

Every deployment also serves a dashboard in the browser, at https://<slug>-admin.<domain>/admin. spky status prints the URL alongside the others.

It is the same information spky status and spky logs give you, live and without a terminal: scheduler and SSP health, end-to-end sync latency, backend health, workflow runs as they happen, and a live log tail. It also carries the actions, so you can restart an SSP, retry a failed workflow run, take a backup or upgrade images from the browser.

Nobody can sign in until you grant someone access with spky admin add <user>. See the admin dashboard for sign-in, the actions and their consequences, and the MCP server it serves for AI agents.

Scaling

Scale your SSP instances horizontally:

# Scale to 3 SSP instances
spky scale ssp 3

You can also set the default SSP count in your sp00ky.yml:

deployment:
  sspCount: 2

Infrastructure Environment Variables

Backends read their environment from the encrypted vault (spky env set). The infrastructure containers Sp00ky Cloud owns — SSP, Scheduler, SurrealDB — take a fixed environment assembled by the control plane. deployment.env is the escape hatch for setting a runtime knob on them, per role and per project:

deployment:
  env:
    ssp:
      SPKY_SSP_MERGE_VIEWS: "true"
      SPKY_SSP_DB_TIMEOUT_SECS: "15"
    scheduler:
      SPKY_SOME_FLAG: "1"
Note

These are not secrets. Unlike spky env set, values are stored unencrypted in the project’s cloud config. Put credentials in the vault, not here.

Keys the control plane manages itself are refused rather than silently overridden: SPKY_DB_*, SPKY_AUTH_SECRET, SPKY_SCHEDULER_URL, SPKY_SSP_ID, SPKY_SSP_ADVERTISE_ADDR, the SSP snapshot/arena directories, SPKY_JOB_CONFIG, and S3_*. Those carry credentials, per-slot identity, or values derived from your deployed backends — overriding them breaks the deployment in ways that are hard to see (a stale SPKY_JOB_CONFIG disables job routing while health checks still pass).

Values take effect when containers are next created, so run spky deploy or spky restart after changing them. Omitting the key entirely keeps the previous setting; an explicit empty map clears it.

deployment.env, the sync: block and the top-level anonymousLiveQueries are read from sp00ky.yml on every deploy, whether spky deploy runs it or a git-linked build does. Both paths write the same values, so a push after a CLI deploy never reverts them.

One pair is set for you: with sync.transport: changefeed in sp00ky.yml, spky deploy merges SPKY_INGEST_TRANSPORT and SPKY_CHANGEFEED_RETENTION into the scheduler and ssp roles (your own keys win on a clash), so the scheduler tails the feed the schema just gained. See Sync transport. Likewise, with sync.queryAllowlist set to warn or enforce, spky deploy merges SPKY_SSP_QUERY_ALLOWLIST=<mode> into the ssp role and publishes the committed allowlist JSON as _00_query_allowlist rows keyed by the frontend’s package.json version; under enforce a missing or stale JSON fails the deploy. See the Query allowlist guide.

SPKY_SSP_DB_TIMEOUT_SECS is the knob most worth knowing here: it bounds how long a single SSP database call may take before it fails and the connection is rebuilt (default 15s, 0 disables). It exists because the SurrealDB HTTP engine has no request timeout of its own and every SSP database call shares one connection, so an unbounded stall parks every route that touches the database. See environment variables and GET /health.

Log Level

logLevel in sp00ky.yml sets RUST_LOG on the Scheduler and SSP containers. Default is info.

# Single value applies everywhere
logLevel: info

Use a { dev, cloud } map to differ per environment:

# Per-environment: chatty locally, quiet in production
logLevel:
  dev: trace
  cloud: info

The value is forwarded to tracing-subscriber, so target-specific directives work:

# Tracing-style target=level directives also work
logLevel: info,ssp=debug,scheduler=trace

Each spky deploy sends the resolved cloud value to Sp00ky Cloud, which restarts the Scheduler and SSP containers with the new RUST_LOG. Use --upgrade if you also want the newest SSP and Scheduler build at the same time (it does not move a pinned version).

Note

At trace, the Scheduler logs every replica query and every record it ingests during bootstrap. Useful for diagnosing “why isn’t this row showing up?” See Logs & Monitoring.