Guide

saasie.yaml

saasie.yaml, in full

THE BLUEPRINT

saasie.yaml describes the repository, not one deployment. It holds no names,
no hostnames and no connection strings: every deployment of it gets its own
databases, with their own generated passwords, and its own hostnames. Today
that is production, from main; the file is written this way so that what
deploys it later — a preview branch, a second environment — needs no edit.

That is why environment values can be references rather than literals: the
control plane resolves them once the thing they point at exists.

  version: 1

  databases:
    db:
      engine: postgres          # postgres | redis
    cache:
      engine: redis

  batteries:                    # optional
    analytics:                  # no settings — the caps are the platform's
    files:
    queues:
    secrets:                    # except this one: the names it may read
      - STRIPE_SECRET_KEY

  services:
    backend:
      dockerfile: backend/Dockerfile   # relative to the repo root
      context: .                       # build context, relative to the root
      port: 3000                       # what the container listens on
      health:
        path: /health                  # absolute path, served on that port
      env:
        LOG_LEVEL: info                # a literal
        DATABASE_URL: { database: db, property: url }
        API_URL: { service: backend, property: internalUrl }

Every field above is required except env, databases and batteries. Nothing
has a default: a value a deployment depends on is written down, so reading
the file tells you what will run without having to know what was left out. At
least one service is required.

REFERENCES

  { database: <name>, property: <property> }
    postgres:  url, host, port, name, user, password
    redis:     url, host, port, password
    Asking a redis for "user" is a parse error, not a variable that
    resolves to nothing at deploy time.

  { service: <name>, property: <property> }
    url          public HTTPS URL — what a browser should call
    internalUrl  in-cluster URL — what a sibling service should call
    host, port

  { battery: <name>, property: <property> }
    analytics:   url, token
    mail:        url, token, from
    inference:   url, token
    secrets:     url, token
    files:       url, token
    queues:      url, token
    Only for a battery declared under "batteries:". See: saasie docs
    batteries

    There is no reference that resolves to a secret's value, on purpose.
    An env var is fixed when the container starts, so rotating one would
    mean redeploying and the value would sit in the pod spec. Fetch them
    from the secrets API at boot instead.

Secrets are not written here. A database password reaches your service as a
reference, already resolved.

Unknown keys are rejected rather than ignored, so a typo is an error at push
time and not a setting that silently did nothing.

Check a file: saasie validate

The same text, on your machine: saasie docs blueprint