Status: Accepted · 2025-11
The repository previously used <service>/<fqdn>/docker-compose.yaml — five
directories, each with its own compose file, all for services running on the
same host:
prometheus/prometheus.matrix.elysium/docker-compose.yaml
grafana/prometheus.matrix.elysium/docker-compose.yaml
loki/prometheus.matrix.elysium/docker-compose.yaml
alloy/prometheus.matrix.elysium/docker-compose.yaml
snmp-exporter/prometheus.matrix.elysium/docker-compose.yaml
This looked like it was designed for many hosts, but the hostname level had exactly one value, and that value appeared nowhere in the documentation. Worse, the split actively broke things:
grafana's compose declareddepends_on: [prometheus, loki], but those services were defined in other compose files. Compose rejects this outright — the file could not start.- Services could not resolve each other by name, so every cross-reference was a
hardcoded IP (
10.0.99.20appeared five times across two files). - Five separate
docker compose upinvocations, in an order nothing recorded. - No shared network, no ordering, no health gating.
One directory per stack, where a stack is the set of services deployed together as a unit:
stacks/observability/
├── compose.yaml # all six services
├── prometheus/ loki/ grafana/ alertmanager/ alloy/ snmp-exporter/
Host-to-stack mapping lives in docs/architecture.md, not in the directory
tree. A second host means a second directory under stacks/.
- Services resolve each other by name on a shared compose network, so the
hardcoded monitoring-host IP disappeared from both
prometheus.yamlandconfig.alloy. depends_onwithcondition: service_healthynow works, so Grafana does not start before its datasources are ready.- One
make upinstead of five ordered invocations. docker compose configvalidates the whole stack at once, which is what makes the CI job meaningful.- The tradeoff: restarting one service means
docker compose up -d <service>rather than acting on an isolated directory. In practice these six services are always deployed and upgraded together, which is the definition of a stack. - Directory names no longer encode which host they run on. That information moved to documentation, where it can be kept accurate — the FQDN in the old paths had already drifted out of every other document.