How it works

One description in. A running stack out.

The mechanism, for the engineer who wants to know what actually happens between a commit and a service answering on its hostname.

Self-describing

Every template describes itself

Every one of the 182 public service templates ships a metadata file beside it — we call it a sidecar — and the control plane's service catalogue is generated from them.

ansible/templates/services/postgres.meta.yaml — verbatim

description: PostgreSQL 17 relational database with health checks.
icon: database
category: data
tags: [sql]
endpoints:
- name: main
  ingress_flag: stack_postgres_ingress_expose
  host_flag: stack_postgres_host_expose
  port_var: stack_postgres_port
  default_port: 5432
  acl_var: acl_postgres
credentials:
- name: postgres_password
  kind: password
  autogenerate: true
- name: postgres_admin_username
  kind: username
  default: admin

so the catalogue can

  • Show it — name, category, icon, in a grid nobody hand-writes.
  • Expose it — the endpoint, and the two flags that decide who can reach it.
  • Guard it — the ACL variable it honours.
  • Provision it — which credentials it needs, and which to generate.

A linter enforces the sidecar. A service that does not describe itself does not land. That is why a UI can render controls for it, and why software — not just people — can reason about the stack.

Browse the catalogue

Deterministic

The merge request is the change

Same description, same bytes. Run the render again and nothing changes. Change one line and only that lands.

the diff

  stack_postgres_port: 5432
- stack_postgres_ingress_expose: false
+ stack_postgres_ingress_expose: true
  acl_postgres: internal

the render

labels:
  traefik.tcp.routers.postgres.rule: HostSNI(`*`)
  traefik.tcp.routers.postgres.entrypoints: postgres
  traefik.tcp.middlewares.acl-postgres.ipallowlist: …

Because the compose file is generated, reverting a stack is reverting a commit and re-rendering. There is no drifted hand-edit on the box to reconcile — hand-editing generated output is banned, and the generated files are not even committed.

contexts, not copies

local dev staging production are the same templates with a different values file. There is no per-environment fork.

Generic by rule

One fix reaches every stack

Never a site-specific template. When a project needs something new, the engine grows — it does not accrete a special case.

One security update, inherited by every stack. One fix, inherited by every stack. That is what a single engine buys, and why the template is treated with the care you would give the estate.

A holding page needed shipping for a client portal. The repo was static HTML; the obvious move was a one-off nginx template. Instead, the generic static-site builder gained a copy type — twenty-odd lines — and two other estates got it the same day, without asking.

The pressure to write a one-off is met with a template that generalises, so the engine gets better under load instead of accreting special cases.

Proof of the rule: one engine spans a 67-service stack and a 2-service lab.

The whole lifecycle

From first render to verified restore

  • Ingress & security headersDeclared per service. Three exposure patterns: network-only, host port, public hostname. Anything routed gets the shared secure-headers middleware and per-project network isolation by default; TLS is one flag and a provider away.
  • SecretsVault-encrypted at rest in the config repo, decrypted only at render, referenced by name; mg vault to manage them. Nothing plaintext, nothing hand-copied.
  • ObservabilityMetrics, logs, traces, alerting and dashboards — rendered in, one flag away per service, not bolted on afterwards. 31 of the 182 templates are observability alone.
  • Data protectionVolume, database and directory backups on independent schedules, remote sync, restores that are tested. Rendered in, one flag away.
  • ImagesStemcells, built and patched in one place, one provenance for every machine.
  • DiagnosticsA tools container on the stack network — because you will need to look inside.

Ten words we use

The vocabulary, once

estate
One product’s complete stack — its services, ingress, network and data — rendered from one configuration repository.
context
One environment’s values for an estate: local, staging, production. Same templates, different context.
render
Turning the description into the runtime: the compose file, every service’s environment, the stack configuration.
stamp
A render that is deterministic. Same input, byte-identical output, every time.
stemcell
A hardened, locked-down base image we build and patch. A service picks one by naming its role, instead of carrying a Dockerfile of its own. Standard OCI images; they run on any container runtime.
sidecar
The metadata file beside every service template: what the service is, what it exposes, what it needs. A file, not a container.
catalogue
Every service template, listed from its sidecar. Nothing in it is typed by hand.
slot
A feature branch running beside main on the same stack, with its own hostname, data and queue names.
worktree
Git’s way of checking out a second branch beside the first. A slot is one.
MCP
The Model Context Protocol: the open standard an AI assistant uses to call tools. The engine’s descriptions are readable over it.
Request a walk-through

micro‑glue is part of the Microcelium tooling that builds your application, and what it builds is yours to keep. If you run several products on machines you own and want them built the same way every time, that is the conversation.