The container factory under Microcelium

Describe it. Render it. Run it.

Describe your services once. micro‑glue renders the whole production runtime — ingress, TLS, monitoring, secrets, backups — and keeps it identical everywhere it runs. The compose file is the least of what comes out.

$ mg config generate -c production
$ docker compose up -d

Two commands, and it is running.

you write

nginx-microcelium-static:
  description: nginx ingress for the Microcelium site.
  flag: enable_nginx_microcelium_static
  service_template: web-infra/static-site-ingress.service.j2
  volume_template:  web-infra/static-site-ingress.volume.j2

config/stack.yaml — a real entry

you get

  • docker-compose.yamlthe least of it
  • stack/traefik/routing · TLS · headers
  • stack/prometheus/ grafana/metrics · alerts · dashboards
  • services/*/.envsecrets, by name
  • backups · restoreson their own schedule
182public service templates
every one describes itself
1000sof deployments
ours and our customers’
6stemcell images
every service runs on one
2016→10 years
one idea

What comes out

The compose file is the least of it

One YAML description. What renders is the whole runtime — not a compose file with the plumbing left as an exercise.

docker-compose.yaml            ← the least of it
services/<svc>/.env            one per service
stack/
├── traefik/                   static · dynamic · redirects · security headers
├── prometheus/                scrape config · alert rules
├── grafana/                   datasources · dashboards
├── alertmanager/  loki/  tempo/  alloy/
├── mysql/init/                init SQL
├── nginx/<site>/              per-site config
├── env/                       infrastructure env
└── certs/  tools/

Ingress and TLS. Metrics, logs, traces, alerting, dashboards. Database init. Secrets, referenced by name and never in plaintext. Backups and data protection on their own schedules. All rendered from the same description, so none of it can drift from the services it serves.

stack/ is ephemeral. Delete it and a re-render rebuilds it, byte for byte. The images it builds are standard OCI images and run on any container runtime, Kubernetes included.

Stemcells

No Dockerfiles

You describe a service. You do not build an image for it.

the usual way

Dockerfile                 × 10
docker-compose.yml         × 10
.env                       × 10
traefik labels             by hand
monitoring                 "who set that up?"

with micro-glue

config/stack.yaml
config/environments/production.yaml
$ mg config generate -c production

Services run on stemcells — phpfpm-nginx, py-stemcell, nodejs-stemcell and friends — configured by role. A stemcell is a base image we build and patch — 6 of them, in PHP, Python and Node.js families — and a service picks one by naming its role. They are hardened, locked-down images: built by us, patched in one place, one provenance for every machine we build.

Your own proprietary services ride the same stemcells. A customer's application containers are built and patched through the same process as the platform's — one provenance for theirs and ours — and land in their registry, not a public one.

One engine, two ways it runs

A laptop, or a fleet

Same templates serve a human running mg on a laptop and an unattended queue job on the fleet.

laptop

$ mg config generate -c local
$ docker compose up

Engineers run this on a laptop; the fleet runs the identical render unattended. Same bytes either way.

control plane

substrate stack compile   → .stack.tgz, version-stamped
substrate stack deploy-bundle → a fleet machine

The same render, non-interactively: image refs rewritten at the registry, source repos staged, packaged as a named artefact. Deploy the same bundle to a second machine and know it is the same bytes. The target has no micro-glue on it at all.

Local development exercises the real production mechanism, not a simulation of it. And micro-glue fills a prepared machine — Substrate builds the machine first.

Go deeper

Where to go next

  • How it works → Self-describing templates, the merge request as the change, an engine that gets better under load, and the lifecycle from first render to verified restore.

  • Built for software factories → Several estates on one machine, several branches of one estate as slots, everything stamped the same way — and what that unlocks.

  • Agents → Queryable, not just executable: the same descriptions that render a stack answer an assistant over MCP.

  • The catalogue → 182 services, described by themselves, rendered from the engine's own sidecars.

Ten years of the same idea

It went from tidying our own playbooks to building whole platforms

What it is for never changed: describe the thing once, render it correctly everywhere, own the result. The history, 2016 to now →

Part of Microcelium

The container factory of the layer you own

Substrate declares and builds the machine: VMs, networks, firewalls, disks. micro-glue fills it with services. Above them, Loom runs the intelligence and Prism the experience.

It is part of the Microcelium tooling that builds your application, and what it builds is yours to keep. If it is the shape of thing you need, talk to us.