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 catalogueDeterministic
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 vaultto 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
mainon 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.
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.