Github|...

Backend options

Auth tokens, request timeouts, environment variables, and running a backend you host yourself.

Everything on this page is optional. A backend works with just spec, baseUrl and method. See Add a backend.

Authentication

Add an auth block and the job runner sends Authorization: Bearer <token> on every request to that backend.

sp00ky.yml
apps:
  api:
    type: backend
    baseUrl: https://api.example.com
    spec: ../api/openapi.yml
    auth:
      type: token
      token: { vault: API_TOKEN }
    method:
      type: outbox
      table: job
      schema: ./src/outbox/api.surql

The token is a literal, an ${ENV_VAR} reference, or a { vault: KEY } lookup resolved at deploy time. See Environment variables. Validate it on your side:

import { bearerAuth } from 'hono/bearer-auth';

app.use('/*', bearerAuth({ token: process.env.API_AUTH_TOKEN }));

type: token is the only auth type today.

Timeouts

The job runner allows 10 seconds per HTTP request by default. Long-running work (LLM calls, video encoding, large imports) needs a higher ceiling.

sp00ky.yml
apps:
  agent:
    type: backend
    spec: ./openapi.yaml
    baseUrl: http://host.docker.internal:8767
    method:
      type: outbox
      table: jobs_agent
      schema: ./src/outbox/agent.surql
    deploy:
      dockerfile: ./Dockerfile
      port: 8767
      timeout: 120               # allow up to 2 minutes per request
      timeoutOverridable: true   # let the client set per-job timeouts

With timeoutOverridable: true, the client can shorten or extend an individual call:

await db.run('agent', '/chat', { message: 'Hello' }, { timeout: 60 });

When it’s false (the default) the timeout option is ignored and the deploy-time value always wins.

Note

A timeout counts as a failed attempt: the row’s errors array grows and the job retries according to max_retries and retry_strategy.

Environment variables

env feeds variables into the backend’s container. It takes a file path, an inline map, vault, or a per-environment map of any of those.

sp00ky.yml
apps:
  api:
    type: backend
    # …
    env:
      dev: ".env.local"
      cloud: "vault"

Full syntax, layering rules and the auto-injected variables are on Environment variables.

Deploy settings

deploy controls how Sp00ky Cloud builds and runs the backend.

sp00ky.yml
apps:
  api:
    type: backend
    # …
    deploy:
      dockerfile: ../api/Dockerfile
      port: 3660
      healthcheck: /health
      expose: true
      timeout: 30
FieldPurpose
dockerfileDockerfile to build the image from.
contextBuild context directory (default: the directory of sp00ky.yml).
portPort your service listens on inside the container.
healthcheckHTTP path that answers 2xx when the service is ready. Probed by the uptime monitor, and required for a backend on a dedicated machine.
exposePublish the backend at https://<slug>-<name>.<domain>. Off by default: an unexposed backend is reachable only by the SSP (and a custom domain can only point at an exposed one).
grpc_portA second, gRPC (h2c) port, published at <slug>-<name>-grpc.<domain>.
cmdOverride the image’s ENTRYPOINT/CMD.
timeoutPer-request timeout in seconds (default 10).
timeoutOverridableLet the client override timeout per call.
resourcesCPU, memory and disk for the container (see below).

Resources

deploy.resources sets the container’s CPU, memory and disk. Omit it and the app gets the defaults; set only the fields you want to change.

sp00ky.yml
apps:
  api:
    type: backend
    # …
    deploy:
      dockerfile: ../api/Dockerfile
      port: 3660
      resources:
        vcpus: 2
        memory: 2048
        disk: 10
FieldUnitDefaultMinimum
vcpuscores11
memoryMB512128
diskGB51

Below a minimum, spky deploy fails validation rather than creating a container the kernel would kill on startup. The same block works for frontend apps.

Note

Resources apply when the container is created, so a change takes effect on the next spky deploy — not on the running container.

This sizes your apps. The database, scheduler and SSP are sized by the platform from your plan and aren’t configurable in sp00ky.yml.

Hosting it yourself

Set hosting: external and Sp00ky won’t build or deploy the service. It only calls the baseUrl you give it. Useful for a backend that already lives somewhere, or one that has to run inside your own network.

sp00ky.yml
apps:
  api:
    type: backend
    hosting: external
    baseUrl: https://api.example.com
    spec: ../api/openapi.yml
    method:
      type: outbox
      table: job
      schema: ./src/outbox/api.surql

Running on a machine pool

runOn moves a backend’s jobs off the core host onto machines of their own, created while there is work and destroyed when there is not. The backend then gets no always-on container.

apps:
  renderer:
    type: backend
    runOn: { pool: render }   # a pool declared under pools: in sp00ky.yml

The backend itself is unchanged: it still answers a POST per job. What a pool needs from it (deploy.port, deploy.dockerfile, ideally deploy.healthcheck) and what changes on the machine (no private network, so no injected database variables) is in Machine pools.

Running on a dedicated machine

runOn: { machine: <name> } gives an always-on backend a Hetzner VM of its own instead of a container on the shared host. It stays reachable exactly as before (expose, custom domains, outbox jobs); only where it runs changes.

machines:
  api-box: { type: cx33, locations: [fsn1] }

apps:
  api:
    type: backend
    runOn: { machine: api-box }
    deploy: { dockerfile: ./api/Dockerfile, port: 8080, healthcheck: /health, expose: true }

A dedicated backend needs deploy.port and deploy.healthcheck; deploy.resources is ignored (the machine type is the size). The lifecycle, what spky deploy shows, and the limits are in Dedicated machines.

Limiting where an app runs

scope keeps an app out of an environment where it doesn’t belong.

ValueEffect
allDefault. Runs locally and in the cloud.
devOnlyOnly under spky dev. Mail catchers, fake payment providers, seed jobs.
cloudOnlyOnly in deployed environments.
sp00ky.yml
apps:
  mailpit:
    type: docker
    scope: devOnly
    image: axllent/mailpit
    ports:
      - "8025:8025"