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 both become the same kind of app inside
the platform, with the same lifecycle, operations and
observability. The only difference is where the container
image comes from.
This chapter covers that difference and how the two kinds combine.
kind: Application (your code)
An Application manifest describes an application built from a
source repository. You own the code, and the manifest sits in
the repository root. At deploy time the platform builds an
image from that source, pushes it to a container registry, and
deploys the image to the target cluster. The manifest’s build
block says what to build (which Dockerfile, which context); the
rest of the manifest describes how the resulting image runs.
This is the path for deploying your own service: a web frontend, a backend API, a worker, anything you write and iterate 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, without the
build pipeline in front of it.
CatalogApp is not limited to entries Flui curates. Any
container image, yours or someone else’s, can become a
deployable application by wrapping it in a CatalogApp
manifest. Declare its registry coordinates, the port it listens
on, the healthcheck and the volumes it needs, and you can run
it through Flui the same way as the curated entries. The
curated catalog and a manifest you write follow 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 the same inside the platform. The same commands stop, start, restart, scale and delete them. The same dashboard views show their logs, metrics, status and crashes. The same release history records every deploy and rollback. Flui has one toolchain for both, and the dashboard files apps by what they do (Applications, Data, System) rather than by where the image came from.
Three flavours of catalog entry
The catalog has three kinds of entry, 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
end goal; your
Applicationis built on top of them. - Composed. An entry that bundles several coordinated workloads installed together as one unit: a database, a cache and an app tier, say, provisioned and torn down as one atomic install. Each bundled component is rendered as its own workload, the components come up in dependency order, and the whole stack shows up as a single bundle in its list. A data store it bundles is also listed under Data. See Composed catalog apps for details.
Composing catalog entries
Catalog entries also combine with each other. A standalone
catalog entry can declare that it needs a building-block entry
(typically a database or a queue) to work, and at install time
you pick how the dependency is satisfied:
- A dedicated instance is provisioned with the consumer, in the same install operation. The building block is created first and the consumer once the building block is healthy, with the credentials the building block generates injected into the consumer’s configuration.
- An existing instance already deployed on the cluster is reused. The install deploys only the consumer and wires it to the existing building block, whose lifecycle is not part of this operation.
Either way, consumer and building block each get their own entry (the consumer under Applications, the building block under Data), each with its own lifecycle and operations once they are running.
One manifest, more than one install
A manifest is a file. An install is a running thing on a cluster. The difference matters when you want one manifest running twice, such as production and staging from the same repository on the same cluster.
Both installs read the same flui.yaml. They cannot both use
the name the file gives, and they cannot both answer on the
hostname the file names. So three fields can be overridden
when you install:
- name: what this install is called;
- exposure:
publicorinternal; - domain: the hostname it answers on.
Everything else stays with the manifest: the build, the port, the resources and the configuration defaults. The overrides are the few things that belong to this copy rather than to the code.
The name is part of the identity
On the Application path an app is identified by four things
together: the cluster, the repository, the branch and the
name. So changing the name does not rename anything. A deploy
carrying a name Flui has not seen installs that repository a
second time, next to the first.
This part surprises people. Exposure and domain are remembered on the install and keep taking precedence over the manifest on later deploys; otherwise the next deploy from anyone’s machine would quietly move an install back to the manifest’s hostname. The name is not remembered, because it is what the lookup uses to find the install in the first place. Pass it on every deploy that targets that install. If you leave it off once, the next deploy targets a different application.
The catalog side does not have that problem
Installing a catalog entry twice always produces two separate installs, each with its own generated identifier. A second install never lands on top of the first, whatever you call it. Here the name is a label you read in the app list, not a key.
Exposure works differently too: an entry offers the public or internal choice only if it declares that it can run privately. The others run the way their manifest says.
Where each side lives
Where the pieces sit for each kind:
kind: Application | kind: CatalogApp | |
|---|---|---|
| Manifest | In the user’s repository | Curated by the catalog, or user-authored against the spec |
| Image | Built from source by the platform’s build pipeline, pushed to a registry | Pulled from a registry; no build step |
| Configuration | build + the runtime blocks | Installation parameters published by the entry |
| Install-time overrides | Name, exposure and domain; the name is part of the app’s identity | Name and address; exposure only where the entry allows it |
| Lifecycle operations | The same on both sides | |
| Observability | The same on both sides |
Writing a custom catalog entry
Anything that runs as a container can be a CatalogApp. The
requirements are light: the image must be reachable from the
cluster, the manifest must declare the port and the
healthcheck the runtime uses to know the app is up, and any
persistent state the app keeps has to be expressible as a
volume. You can write a CatalogApp for any image you want and
deploy it through the same path as the curated entries.
The curated catalog is built the same way: each entry is a
CatalogApp manifest, written once, reviewed, and made
available to everyone.
Where this chapter goes from here
- The app concept: what both kinds produce, regardless of where the image came from.
- The flui.yaml manifest: the shared envelope both kinds sit under.
- Composed catalog apps: the composed flavour in depth, with components, auth modes, options and the install-time templating.
- Install an application from the catalog: finding an entry, the answers it asks for at install time, and the name, address and exposure you can override.
- Deploy an application from your repository:
the
Applicationpath end to end, including what--namedoes to identity. - Framework templates: how
templates speed up the
Applicationpath. - The build pipeline:
what happens between an
Applicationmanifest and a running container.