Github|...

Environment Variables

Most applications need environment variables — database URLs, API keys, feature flags, third-party credentials. Sp00ky provides a single env property on every app in sp00ky.yml that handles environment variables across local development and cloud deployment.

Additionally, Sp00ky auto-injects a set of SPKY_* variables into every app so your services can connect to infrastructure without manual configuration.

Auto-Injected Variables

Every app (backend and frontend) automatically receives these variables — no configuration needed:

VariableDescriptionDev exampleCloud example
SPKY_ENVCurrent environmentdevcloud
SPKY_DB_URLSurrealDB HTTP endpointhttp://localhost:8666http://10.100.1.10:8000
SPKY_DB_WSSurrealDB WebSocket endpointws://localhost:8666ws://10.100.1.10:8000
SPKY_DB_NSSurrealDB namespaceFrom sp00ky.ymlFrom deployment config
SPKY_DB_NAMESurrealDB database nameFrom sp00ky.ymlFrom deployment config
SPKY_DB_USERSurrealDB usernameFrom sp00ky.ymlroot
SPKY_DB_PASSSurrealDB passwordFrom sp00ky.ymlAuto-generated
SPKY_SSP_ADDRSSP endpointhttp://localhost:8667http://10.100.1.30:8667
SPKY_SCHEDULER_URLScheduler endpoint (cluster mode)http://localhost:9667http://10.100.1.20:9667

Use SPKY_DB_URL for HTTP-based SDKs (JavaScript, Python) and SPKY_DB_WS for WebSocket-based SDKs (Rust SurrealDB client). Both always point to the same database — just different protocols.

TypeScript
// JavaScript / TypeScript
const db = new Surreal();
await db.connect(process.env.SPKY_DB_URL);
await db.signin({
  username: process.env.SPKY_DB_USER,
  password: process.env.SPKY_DB_PASS,
});
await db.use({
  namespace: process.env.SPKY_DB_NS,
  database: process.env.SPKY_DB_NAME,
});
python
# Python
import os, httpx
url = os.environ["SPKY_DB_URL"]
ns = os.environ["SPKY_DB_NS"]
db = os.environ["SPKY_DB_NAME"]
resp = httpx.post(f"{url}/sql", content="SELECT * FROM user;",
    headers={"surreal-ns": ns, "surreal-db": db},
    auth=(os.environ["SPKY_DB_USER"], os.environ["SPKY_DB_PASS"]))
Note

Auto-injected variables can be overridden — if you set SPKY_DB_URL in your env config, your value takes precedence over the auto-injected one.

Custom Environment Variables

Beyond the auto-injected SPKY_* variables, you can provide your own using the env property. It accepts several forms.

From a File

A .env file with one KEY=VALUE per line. Comments (#) and blank lines are ignored.

yaml
apps:
  api:
    type: backend
    env: ".env.local"
    # ...

The path is resolved relative to your sp00ky.yml.

Warning

Don’t commit .env files containing secrets to version control. Add them to .gitignore and use the encrypted vault for production secrets.

Inline

Define variables directly in the config:

yaml
apps:
  api:
    type: backend
    env:
      LOG_LEVEL: debug
      PORT: 3000
      ENABLE_CACHE: true
    # ...

Values can be strings, numbers, or booleans.

From the Vault

For production secrets, use the encrypted vault:

yaml
apps:
  api:
    type: backend
    env: "vault"
    # ...

This loads all variables from the vault. To load only specific ones, pass a whitelist:

yaml
apps:
  web:
    type: frontend
    env:
      vault: [VITE_API_URL, VITE_PUBLIC_KEY]
    # ...
Note

Vault variables must be set up first with spky cloud env init and spky cloud env set. See Cloud Environment Variables for the full setup guide.

Per-Environment

Use different sources for local development vs cloud deployment:

yaml
apps:
  agent:
    type: backend
    env:
      dev: ".env.local"         # used during spky dev
      cloud: "vault"             # used during spky cloud deploy
    # ...

Each side accepts any form — a file path, inline map, "vault", a vault whitelist, or an array.

Layering Multiple Sources

Combine multiple sources in an array. Later entries override earlier ones by key:

yaml
apps:
  api:
    type: backend
    env:
      - "vault"                        # 1. start with all vault secrets
      - ".env.overrides"               # 2. override specific values from file
      - { LOG_LEVEL: debug }           # 3. final inline override
    # ...

Arrays also work inside per-environment splits:

yaml
apps:
  agent:
    type: backend
    env:
      dev:
        - ".env.local"
        - { DEBUG: true }
      cloud:
        - "vault"
        - ".env.cloud.overrides"
    # ...

Full Example

A realistic sp00ky.yml showing environment variables across a frontend and two backends. Note that SPKY_DB_* variables are auto-injected — you only need to configure app-specific secrets.

yaml
apps:
  web:
    type: frontend
    dev:
      type: npm
      script: dev:app
    deploy:
      dockerfile: ./Dockerfile
      port: 3000
    env:
      dev:
        VITE_API_URL: "http://localhost:8765"
      cloud:
        vault: [VITE_API_URL, VITE_PUBLIC_KEY]

  api:
    type: backend
    spec: ./api/openapi.yml
    method:
      type: outbox
      table: job
      schema: ./schema/src/outbox/api.surql
    # No env needed — SPKY_DB_* is auto-injected

  agent:
    type: backend
    spec: ./agent/openapi.yml
    method:
      type: outbox
      table: jobs_agent
      schema: ./schema/src/outbox/agent.surql
    env:
      dev: ".env.agent.local"
      cloud:
        - "vault"
        - { MAX_TOKENS: 4096 }

How Variables Are Injected

ContextBehavior
spky dev (npm, uv)SPKY_* auto-injected + user vars set in the spawned process environment
spky dev (docker)SPKY_* auto-injected + user vars passed as -e KEY=VAL flags to docker run
spky cloud deploySPKY_* auto-injected by the orchestrator + user vars from the deployment manifest
"vault" in devThe CLI fetches decrypted variables from the Sp00ky Cloud API (requires spky cloud login)
"vault" in deployVariables are fetched server-side and included in the manifest

User-provided variables always take precedence over auto-injected SPKY_* variables.

Validating Your Config

Run spky lint to check that all referenced env files exist before deploying:

Bash
$ spky lint
  Parsed sp00ky.yml successfully.

  warning: apps.api.env file not found: .env.local

  No errors. 1 warning(s).