Four more of the catalogue: registry, redis, umami, grafana

Converted from the arrangement being replaced, in its shapes rather
than theirs.

The registry is the manifest the lab already proved, promoted: names
its image by digest and is never built (04-ISSUES/029), provides the
artifact store, claims it once per machine.

Redis is the third provision after a database and a bucket, and the
first whose tenancy is a pattern in a shared keyspace rather than a
namespace something else enforces. Its provisioner mirrors the postgres
one's contract line for line — the manifest, the sealed per-consumer
files, the mark, the withdrawal of orphans — and speaks RESP directly:
five commands are needed, and a client library large enough to hide
them would be most of the program's size. A prefix Redis would read as
a pattern is refused, because the grant must mean what the manifest
said; grants are persisted with ACL SAVE, or said loudly, because a
cache that forgets its tenants on restart reports success until then.

Umami asks the mesh for its database and a generated app secret, and
carries no state of its own — the arrangement being replaced ran a
bundled second postgres beside it. Grafana keeps its dashboards in a
declared directory with the image's own owner. Both listen on 3000, as
does the forge — which is the mesh's port assignment earning its keep.

Traefik is deliberately not converted: the mesh's route provider is
mesh-route-proxy, which speaks route grants natively, and a traefik
that consumed them would be an adapter nobody has written pretending
to be a conversion.

All images pinned by real digests, resolved on this workstation today.
This commit is contained in:
2026-09-01 22:44:53 +02:00
parent 38d4e77cec
commit 8c4a478b09
9 changed files with 677 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
{
"module": "grafana",
"version": "1",
"own-secrets": {
"admin": "/var/lib/grafana-module/admin.secret"
},
"capabilities": [
"container-runtime"
],
"listens": [
{
"port": 3000,
"protocol": "tcp",
"from": "mesh",
"why": "the dashboards. Also 3000 inside, like the forge - which is the mesh's port assignment earning its keep"
}
],
"resources": [
{
"id": "state",
"type": "directory",
"path": "/var/lib/grafana-module",
"mode": "0700"
},
{
"id": "server-env",
"type": "file",
"path": "/var/lib/grafana-module/server.env",
"mode": "0600",
"content": "GF_SECURITY_ADMIN_PASSWORD=${secret:admin}\n"
},
{
"id": "data",
"type": "directory",
"path": "/services/grafana/data",
"mode": "0700",
"owner": "472:472"
},
{
"id": "server",
"type": "container",
"name": "grafana",
"image": "grafana/grafana@sha256:f772d434e8fab0049deb2b1b30abd43342bcfca1537614aa8d36080232cf4283",
"env-file": [
"/var/lib/grafana-module/server.env"
],
"ports": [
"3000"
],
"volumes": [
"/services/grafana/data:/var/lib/grafana"
]
}
]
}
+105
View File
@@ -0,0 +1,105 @@
{
"module": "redis",
"version": "1",
"provides": [
{
"name": "redis-cache",
"scope": "mesh"
}
],
"capabilities": [
"container-runtime"
],
"serves": {
"redis-cache": {}
},
"receives": {
"redis-cache": "/var/lib/redis-module/grants/mesh.json"
},
"grants": {
"redis-cache": "/var/lib/redis-module/grants"
},
"own-secrets": {
"default": "/var/lib/redis-module/default.secret"
},
"listens": [
{
"port": 6379,
"protocol": "tcp",
"from": "mesh",
"why": "modules on any machine that were granted a cache"
}
],
"resources": [
{
"id": "state",
"type": "directory",
"path": "/var/lib/redis-module",
"mode": "0700"
},
{
"id": "grants-dir",
"type": "directory",
"path": "/var/lib/redis-module/grants",
"mode": "0700"
},
{
"id": "data",
"type": "directory",
"path": "/services/redis/data",
"mode": "0700"
},
{
"id": "server-conf",
"type": "file",
"path": "/var/lib/redis-module/redis.conf",
"mode": "0600",
"content": "requirepass ${secret:default}\naclfile /data/users.acl\nappendonly yes\ndir /data\n"
},
{
"id": "acl-seed",
"type": "file",
"path": "/services/redis/data/users.acl",
"mode": "0600",
"content": ""
},
{
"id": "net",
"type": "network",
"name": "redis"
},
{
"id": "server",
"type": "container",
"name": "redis",
"image": "redis@sha256:ff02b58f971e7d7d156a1267e283fcbbeee91773b6aa36c49dac28ecfe28eadf",
"network": "redis",
"ports": [
"6379"
],
"volumes": [
"/services/redis/data:/data",
"/var/lib/redis-module/redis.conf:/etc/redis/redis.conf:ro"
],
"args": [
"/etc/redis/redis.conf"
]
},
{
"id": "provisioner",
"type": "container",
"name": "mesh-provision-redis",
"image": "mesh-provision-redis@sha256:0000000000000000000000000000000000000000000000000000000000000000",
"network": "redis",
"env": {
"GRANTS": "/var/lib/redis-module/grants",
"MESH_PROVISION_REDIS": "redis:6379",
"MESH_PROVISION_PASSWORD_FILE": "/run/secrets/default"
},
"volumes": [
"/var/lib/redis-module/grants:/var/lib/redis-module/grants:ro",
"/var/lib/redis-module/default.secret:/run/secrets/default:ro"
]
}
]
}
+52
View File
@@ -0,0 +1,52 @@
{
"module": "registry",
"version": "1",
"provides": [
{
"name": "artifact-store",
"scope": "mesh"
}
],
"claims": [
{
"name": "the-artifact-store",
"scope": "node"
}
],
"capabilities": [
"container-runtime"
],
"serves": {
"artifact-store": {
"port": 5000
}
},
"listens": [
{
"port": 5000,
"protocol": "tcp",
"from": "mesh",
"why": "every machine pulls images and artifacts from here"
}
],
"resources": [
{
"id": "state",
"type": "directory",
"path": "/var/lib/mesh/registry",
"mode": "0700"
},
{
"id": "store",
"type": "container",
"name": "mesh-registry",
"image": "registry@sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373",
"ports": [
"5000:5000"
],
"volumes": [
"mesh-registry-data:/var/lib/registry"
]
}
]
}
+59
View File
@@ -0,0 +1,59 @@
{
"module": "umami",
"version": "1",
"requires": [
"postgres-database"
],
"contributes": {
"postgres-database": {
"name": "umami"
}
},
"binds": {
"postgres-database": "/var/lib/umami/database.json"
},
"secrets": {
"postgres-database": "/var/lib/umami/database.secret"
},
"own-secrets": {
"app-secret": "/var/lib/umami/app.secret"
},
"capabilities": [
"container-runtime"
],
"listens": [
{
"port": 3000,
"protocol": "tcp",
"from": "mesh",
"why": "the analytics pages and the collection endpoint"
}
],
"resources": [
{
"id": "state",
"type": "directory",
"path": "/var/lib/umami",
"mode": "0700"
},
{
"id": "server-env",
"type": "file",
"path": "/var/lib/umami/server.env",
"mode": "0600",
"content": "DATABASE_URL=postgresql://${bound:postgres-database:as}:${secret:postgres-database}@${bound:postgres-database:at}:${bound:postgres-database:port}/umami\nAPP_SECRET=${secret:app-secret}\n"
},
{
"id": "server",
"type": "container",
"name": "umami",
"image": "ghcr.io/umami-software/umami@sha256:fa32d116cf20cad52cbc3fad9a63b46e7fa02299d8f967168eb453d49c476b4a",
"env-file": [
"/var/lib/umami/server.env"
],
"ports": [
"3000"
]
}
]
}