Skip to content

Catalog vs Application

A flui.yaml declares one of two kinds: Application or CatalogApp. They share the same outer envelope and the same identity model, and they end up as the same kind of app inside the platform — same lifecycle, same operations, same observability surfaces. What separates them is one thing only: where the container image comes from.

This chapter is about that distinction, and about how the two combine.

kind: Application — your code

An Application manifest describes an application built from a source repository. The user owns the code and the manifest sits in the repo’s root. At deploy time the platform builds an image from that source, pushes it to a container registry, and then deploys the image to the target cluster. The manifest’s build block carries the what of the build (which Dockerfile, which context, or “let the platform pick”); the rest of the manifest describes how the resulting image should run.

This is the path for “deploy my own service” — a web frontend, a backend API, a worker — anything the user authors and iterates on.

kind: CatalogApp — ready-to-install software

A CatalogApp manifest describes a pre-packaged application whose image already exists on a container registry. The manifest references the image by registry, name and tag, and adds the installation parameters that make it usable: admin credentials to generate, volume sizes, optional features. There is no build step — picking a catalog entry produces the same kind of running app as building one from source, just without the build pipeline in front of it.

CatalogApp is not limited to entries Flui curates. Any container image — yours, someone else’s, public or private — can become a deployable application by wrapping it in a CatalogApp manifest: declare its registry coordinates, the port it listens on, the healthcheck, the volumes it needs, and you have a deployable manifest you can run through Flui the same way the curated entries are. The curated catalog and a user-authored manifest sit on the same path; the only difference is who wrote the file.

The same lifecycle on both sides

Once deployed, an application from source and an application from the catalog behave identically inside the platform. The same commands stop, start, restart, scale and delete them. The same dashboard views show their logs, their metrics, their status and their crashes. The same release history records every deploy and rollback. The platform does not maintain “two toolchains, one for your code and one for packaged software”: both kinds of app live in the same list and are operated the same way.

This homogeneity is the point of having a single manifest envelope and a single app model behind it.

Three flavours of catalog entry

The catalog distinguishes three kinds of entries, by what they are meant to do:

  • Standalone. A complete application that runs on its own and serves its own purpose — an admin tool, a self-hosted service, anything you might install just to use.
  • Building block. An application meant to back other applications rather than be reached directly — most often a database or a message queue. Building blocks are rarely the user’s end goal; they are what a user Application is composed on top of.
  • Composed. An entry that bundles several coordinated workloads installed together as a single unit. The schema supports this shape today; the surrounding tooling for managing composed installs as one object is the next major step on the catalog roadmap.

Composing catalog entries

Catalog entries also compose with each other. A composed catalog entry can declare that it needs a building-block entry (typically a database or a queue) to function, and at install time the operator picks how the dependency is satisfied:

  • A dedicated instance is provisioned alongside the consumer, inside the same install operation: the building block is created first, the consumer on top once the building block is healthy, with the credentials the building block generates exposed to the consumer as injected configuration.
  • An existing instance already deployed on the cluster is reused: the install only deploys the consumer and wires it to the existing building block. The building block’s lifecycle is not part of the current operation.

Either way, consumer and building block end up side by side in the application list, each with its own lifecycle and operations once they are running.

Where each side lives

A short summary of where the moving pieces sit for each kind:

kind: Applicationkind: CatalogApp
ManifestIn the user’s repositoryCurated by the catalog, or user-authored against the spec
ImageBuilt from source by the platform’s build pipeline, pushed to a registryPulled from a public registry; no build step
Configurationbuild + the runtime blocksInstallation parameters published by the entry
Lifecycle operationsThe same on both sides
ObservabilityThe same on both sides

Writing a custom catalog entry

Anything that runs as a container can be a CatalogApp. The contract is light: the image must be reachable from the cluster, the manifest must declare the port and the healthcheck the runtime needs to know the app is up, and any persistent state the app keeps has to be expressible as a volume. A user can write a CatalogApp against any image they want and deploy it through the same path as the curated entries.

The curated set of catalog entries is itself the result of this contract — each entry is just a CatalogApp manifest, written once, reviewed, and made available to everyone.

Where this chapter goes from here