Skip to content

The flui.yaml manifest

flui.yaml is the declarative description of a cloud application that Flui consumes. It is also, by design, an open specification that lives in its own repository and is meant to outlive any single implementation — including Flui itself. Any tool that follows the spec can read, write, validate and deploy a flui.yaml; Flui happens to be the first.

This chapter is about what the manifest expresses, what it deliberately leaves out, and the small set of guarantees the spec carries forward.

A spec, not a config format

The authoritative schema lives in a dedicated repository — flui-cloud/flui-spec — with its own versioning policy, narrative documentation (docs/), JSON Schemas (schemas/), and example manifests (examples/). The TypeScript types and the pure validator are published to npm as @flui-cloud/spec, which Flui pulls in like any other dependency. The schema and the validation logic are not maintained inside Flui’s own codebase — Flui consumes them, it does not own them.

This split is deliberate. A manifest that names a Flui-internal concept, or that requires a Flui-specific extension, would quietly couple users to one implementation. Keeping the spec in its own repo and pulling it in as a dependency makes that coupling impossible by construction: the same file can be consumed by a different tool tomorrow.

Two kinds of manifest

A flui.yaml declares one of two kinds at its root:

  • Application — an application built from a source repository and deployed to a cluster.
  • CatalogApp — a pre-packaged building block (a database, a message queue, an admin tool) installed from a catalog of ready-made entries with the configuration the catalog publishes.

Both share the same outer envelope and the same metadata. They diverge in what they declare under the body, and the distinction between the two is the subject of Catalog vs application. This chapter looks at the Application shape, which is the one users write themselves.

What an Application manifest expresses

An Application manifest is a small set of blocks, each answering one operational question:

  • Name. A stable identifier for the application. It is what every other surface — dashboard, CLI, observability — uses to refer to it, so the spec restricts it to a lowercase form suitable for use in hostnames.
  • How to build the image. A pointer to a Dockerfile in the repository, or a request to let the platform detect the framework and build accordingly. The block stays at the level of what and where, not how the build runs.
  • How to run the workload. The port the container listens on, the healthcheck the platform should probe, the replica count limits, the resource allocation (CPU and memory, either as explicit numbers or as a t-shirt-sized preset), an optional start command override.
  • Configuration and secrets. A list of environment variables. Each entry can carry a plain value inline, mark a value as a secret to be generated, reference an external secret by name, or declare a value the dashboard should prompt the user for at install time.
  • Volumes. Persistent volumes the application needs, each with a name, a mount path, a size and an optional storage class — the latter covered in Storage classes and dedicated placement.
  • Domain. Whether the deploy should produce a public hostname, whether TLS should be provisioned for it, and which certificate flow to use. The endpoint and certificate mechanics behind these flags are covered in DNS as part of the deploy contract and TLS and certificates.

That is the whole vocabulary. There are no other knobs, and there is no escape hatch for cluster-internal resources or provider-specific tuning — that is the next section.

What the manifest deliberately omits

The exclusions are as important as the inclusions:

  • Where it runs. A flui.yaml does not decide which cluster, provider or region it deploys to. The deploy invocation (whichever tool runs it) picks the target. The same file goes to staging on one invocation and to production on the next.
  • Credential values. Secret values never live in the manifest. Secrets are referenced by name, generated by the platform, or prompted from the operator at install time.
  • How the build runs. The manifest expresses what to build (“the Dockerfile in the repo”, “let the platform pick”), not where or how. The build runner is an implementation detail of the tool that consumes the manifest.
  • Runtime-specific resources. The manifest stays above any particular runtime — it describes the application, not the cluster-level shape it eventually takes. How a tool realises the manifest on whatever runtime it targets is the tool’s concern.
  • Implementation-specific extensions. The schema is closed. Fields tied to one tool — internal identifiers, vendor-specific tuning — are not allowed. Additions go through the spec, where every implementation gets to consume them on the same footing.

The spec contract

A manifest valid against a given version of the spec is accepted by every tool that supports that version. The shape of the running application is determined by the manifest plus deploy-time inputs (the target cluster, any explicit overrides at deploy time), and nothing else. Breaking changes to the schema go through a version bump; backwards-compatible additions can land in the current version. Schemas are published with the spec so any tool can validate offline.

Validation

The CLI can validate a manifest against the spec without deploying it — useful as a CI step on every change and as a pre-flight before a real deploy. The check is offline, schema- level, and works for both Application and CatalogApp. The command-level reference lives in the CLI docs.

From manifest to running application

At deploy time, the platform reads the manifest, merges any deploy-time overrides the operator passed — a different image, extra environment variables, a custom domain — and turns the result into whatever the target runtime needs to host the application. The manifest is the intent; what runs on the cluster is the realisation. Each deploy produces this realisation from the manifest again, so the file on disk remains the source of truth for the application’s shape.

Where this chapter goes from here