Docs
The project file

The project file

clusterz.yaml at the root of your repository says how your app runs. Every field is optional.

clusterz.yaml sits at the root of the repository, and the website and cluz both read it. Every field is optional. What you leave out comes from reading the repository, and cluz init writes what it found, so the next deploy follows the file.

services:
  - name: web
    type: web                        # the one service at the app's address
    repo: github.com/acme/shop-web   # a service from another repository
    port: 3000
    health_check: /manifest.webmanifest
    env:
      - key: API_URL
        from_service: api            # http://api:8080 on the app's own network
  - name: api
    type: api                        # private: only the app's services reach it
    root: api                        # the folder the service lives in
    build: buildpack                 # or dockerfile
    build_command: npm run build
    start_command: npm start
    release_command: npm run migrate # runs after the build, before traffic moves
    port: 8080
    health_check: /healthz
    size: { memory_gb: 1, vcpu: 0.5, instances: 1 }
    env:
      - key: API_KEY
        required: true               # a deploy is refused until it has a value
        secret: true
      - key: SESSION_SECRET
        generate: 32                 # a random value, made once
      - key: LOG_LEVEL
        value: info
      - key: REPORTS_URL
        from_database: reports       # that database's connection string
  - name: jobs
    type: worker                     # no port and no address
    root: api
    start_command: npm run jobs
databases:
  - name: main
    kind: postgres                   # or supabase
    for: [api, jobs]                 # each gets DATABASE_URL
  - name: reports
    kind: postgres
    for: []                          # no one gets DATABASE_URL from it
auto_deploy: true
branch: main

The top of the file

FieldWhat it does
servicesThe services of the app, all in one project. Each says what it is with type: the web has the app's address, an api is reached by the app's other services, and a worker listens on no port. Their order decides nothing. Services lists their fields.
databasesThe app's databases, each with a name of its own. Databases in the file lists their fields.
auto_deployWhether a push to the branch deploys. Left out, it does.
branchThe branch that is built. Left out, main.

How the file is read

  • It is read from the repository, so anyone may have written it: a file larger than 256 KiB is refused.
  • A field Clusterz does not know is refused, and so is a value it cannot take. The message names where.
  • On a push, Clusterz applies the file before it builds. If the file does not parse, the project keeps its settings and the build goes ahead. Run cluz up --dry-run to read the same message.
  • When the website's form shows a setting that the file sets, it says so and points to the file to change it.