Files
mesh-catalog/modules/distribution-gate/module.json
T
jschoubben 3249b9a0cc The registry's public name is a second module beside the store, locked by the registry itself
The predecessor serves the registry under a public name, behind htpasswd basic auth, with a
twenty-gigabyte body limit for layer pushes. The mesh's registry has no name, no lock and no
limit — by design inside the mesh, where the private network is the boundary and every node
pulls without an account (hq ADR 0082). Taking the name over must not change that.

A route on `distribution` itself would: contributing a route is requiring one, and the store
is raised at genesis on a node with no proxy. So the public door is `distribution-gate`, a
second registry process on the same volume, behind the registry's own htpasswd (the
predecessor's realm, the predecessor's file, carried in with `secret accept`), with the
route and its limit. It requires the store's storage as a node-scoped provision, so it can
only land beside the store. The store's own door is untouched — no auth, no htpasswd — which
is what keeps the builder's pushes and every node's pulls working.

Both processes read the predecessor's configuration where it changed behaviour: delete
enabled, which tag retention depends on; no per-process descriptor cache, which two
processes over one store cannot share; the CORS headers for the retired interface dropped.

route-adapter writes the limit as the predecessor's own buffering middleware, named after
the router, only when asked for — and skips a route whose limit it cannot read rather than
carrying what the module said not to.

hq ADR 0082/0104, the registry hand-over.
2026-09-23 23:19:12 +02:00

63 lines
3.0 KiB
JSON

{
"module": "distribution-gate",
"version": "1",
"capabilities": [
"container-runtime"
],
"requires": [
"artifact-storage",
"route"
],
"contributes": {
"route": {
"label": "registry-api",
"port": 5001,
"max-request-body": 21474836480
}
},
"own-secrets": {
"htpasswd": "/var/lib/mesh/registry-gate/htpasswd"
},
"listens": [
{
"port": 5001,
"protocol": "tcp",
"from": "mesh",
"why": "the artifact store's public door: the same store behind the registry's own basic auth, reached by the proxy under its public name; the mesh itself pulls from the store's own port and never from here"
}
],
"resources": [
{
"id": "state",
"type": "directory",
"path": "/var/lib/mesh/registry-gate",
"mode": "0700"
},
{
"id": "config",
"type": "file",
"path": "/var/lib/mesh/registry-gate/config.yml",
"mode": "0644",
"content": "# The registry's configuration, written by the mesh from the module's manifest.\n#\n# Carried over from the predecessor's registry.yml where it changed behaviour (novox/hq ADR 0082,\n# the registry hand-over):\n# - storage.delete.enabled: the image's default refuses DELETE on a manifest; the predecessor\n# enabled it, and tag retention and garbage collection depend on it.\n# - no storage.cache: the image's default keeps an in-memory blob-descriptor cache, which is\n# right for one process and wrong for two on one store — the mesh door and the public door\n# are two registry processes sharing this filesystem, and a descriptor cached by one and\n# deleted through the other would say a blob exists that does not.\n# Dropped: the CORS headers, which served the browser interface that is being retired.\nversion: 0.1\nlog:\n fields:\n service: registry\nstorage:\n delete:\n enabled: true\n filesystem:\n rootdirectory: /var/lib/registry\nhttp:\n addr: :5001\n headers:\n X-Content-Type-Options: [nosniff]\nhealth:\n storagedriver:\n enabled: true\n interval: 10s\n threshold: 3\n# The public door's lock, as the predecessor kept it: the registry itself checks basic auth\n# against an htpasswd file — bcrypt entries, one user — under the realm the predecessor\n# announced, so a client that logged in to the old name logs in to this one unchanged.\nauth:\n htpasswd:\n realm: basic-realm\n path: /etc/docker/registry/htpasswd\n"
},
{
"id": "gate",
"type": "container",
"name": "mesh-registry-gate",
"image": "registry@sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373",
"ports": [
"5001:5001"
],
"volumes": [
"mesh-registry-data:/var/lib/registry",
"/var/lib/mesh/registry-gate/config.yml:/etc/docker/registry/config.yml:ro",
"/var/lib/mesh/registry-gate/htpasswd:/etc/docker/registry/htpasswd:ro"
],
"restart-on": [
"config",
"needs-htpasswd"
]
}
]
}