From 157fab5dc8cf3286af5531312c3df9a9c679cfeb Mon Sep 17 00:00:00 2001 From: jochens Date: Wed, 30 Sep 2026 11:59:56 +0200 Subject: [PATCH] matrix: Conduit and Element, told their own name by the route ace runs a Conduit homeserver (matrix.zurag.be, 5.4 GB of RocksDB, federating) and Element Web under HAL, configured by environment with the domain templated in, and Element's config.json carrying matrix.zurag.be literally. A homeserver's server_name is its permanent identity - every user id, room id and signature in the database carries it - and it is the name the module is served under. So it comes from ${bound:route:name-homeserver} (mesh-controller #149), rendered into a conduit.toml the container reads through CONDUIT_CONFIG, and into Element's config.json (base_url, default_server_name, the room directory). Without #149 the render is refused ("name-homeserver"), never written empty. Two routes, one per endpoint: homeserver (label matrix, 6167) and element (label element, 80). Federation needs no 8448: Conduit answers /.well-known/matrix/server with :443, so peers federate through the route. HAL published 8448 on all interfaces, but the router never forwarded it; checked from outside, the well-known, federation version and client versions all answer on 443. Registration defaults to off. HAL ran with CONDUIT_ALLOW_REGISTRATION=true, which on ace means anyone on the internet can create an account with the dummy flow (seen: /register offers m.login.dummy) - on 0.10.13, whose successor 0.10.14 fixes an account-takeover by any local user. Existing accounts are unaffected; the operator decides whether to reopen it. Element's config.json is the one merge:json file (it tolerates `endpoints`), so a machine can add keys. HAL's map_style_url is not carried: it embedded a map-tile API key, which belongs in an assignment if wanted. Images are the digests ace runs (Conduit 0.10.13, Element 1.12.28). Verified: catalogue tests with MESH_CATALOGUE pointed here on mesh-controller main and #149; a resolution on #149 renders both names (matrix.zurag.be, element.zurag.be) into both files and both contributions; throwaway containers of both pinned digests with the rendered files (root 0644, :ro): client versions 200, well-known says matrix.zurag.be:443, register refused M_FORBIDDEN, Element 200 serving the rendered config.json. --- modules/matrix/module.json | 110 +++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 modules/matrix/module.json diff --git a/modules/matrix/module.json b/modules/matrix/module.json new file mode 100644 index 0000000..13964f9 --- /dev/null +++ b/modules/matrix/module.json @@ -0,0 +1,110 @@ +{ + "module": "matrix", + "version": "1", + "capabilities": [ + "container-runtime" + ], + "listens": [ + { + "name": "client", + "port": 6167, + "protocol": "tcp", + "from": "mesh", + "why": "Conduit's client-server and federation APIs over plain HTTP. Both arrive through the route on 443: Conduit answers /.well-known/matrix/server with :443, so other homeservers federate through the proxy and nothing needs the traditional 8448" + }, + { + "name": "web", + "port": 80, + "protocol": "tcp", + "from": "mesh", + "why": "Element Web, the static browser client, served by the image's nginx; reached through its route" + } + ], + "requires": [ + "route" + ], + "contributes": { + "route": { + "homeserver": { + "label": "matrix", + "endpoint": "client" + }, + "element": { + "label": "element", + "endpoint": "web" + } + } + }, + "binds": { + "route": "${dir:state}/route.json" + }, + "resources": [ + { + "id": "state", + "type": "directory", + "mode": "0700", + "place": "." + }, + { + "id": "db", + "type": "directory", + "mode": "0700" + }, + { + "id": "conduit-conf", + "type": "file", + "path": "${dir:state}/conduit.toml", + "mode": "0644", + "content": "# Written by the mesh (modules/matrix). Conduit reads this file (CONDUIT_CONFIG); nothing comes\n# from the environment. server_name is the homeserver's permanent identity: every user id, room id\n# and signature in the database carries it, so it is the name this module is served under\n# (${bound:route:name-homeserver}) and never changes once a database exists.\n[global]\nserver_name = \"${bound:route:name-homeserver}\"\ndatabase_backend = \"rocksdb\"\ndatabase_path = \"/var/lib/matrix-conduit/\"\naddress = \"0.0.0.0\"\nport = 6167\nmax_request_size = 20000000\nallow_registration = false\nallow_federation = true\nallow_check_for_updates = true\ntrusted_servers = [\"matrix.org\"]\n" + }, + { + "id": "element-conf", + "type": "file", + "path": "${dir:state}/element.json", + "mode": "0644", + "merge": "json", + "content": "{\n \"default_server_name\": \"${bound:route:name-homeserver}\",\n \"default_server_config\": {\n \"m.homeserver\": {\n \"base_url\": \"https://${bound:route:name-homeserver}\"\n },\n \"m.identity_server\": {\n \"base_url\": \"https://vector.im\"\n }\n },\n \"brand\": \"Element\",\n \"integrations_ui_url\": \"https://scalar.vector.im/\",\n \"integrations_rest_url\": \"https://scalar.vector.im/api\",\n \"integrations_widgets_urls\": [\n \"https://scalar.vector.im/_matrix/integrations/v1\",\n \"https://scalar.vector.im/api\",\n \"https://scalar-staging.vector.im/_matrix/integrations/v1\",\n \"https://scalar-staging.vector.im/api\",\n \"https://scalar-staging.riot.im/scalar/api\"\n ],\n \"bug_report_endpoint_url\": \"https://element.io/bugreports/submit\",\n \"uisi_autorageshake_app\": \"element-auto-uisi\",\n \"show_labs_settings\": true,\n \"room_directory\": {\n \"servers\": [\n \"${bound:route:name-homeserver}\",\n \"matrix.org\",\n \"gitter.im\",\n \"libera.chat\"\n ]\n },\n \"enable_presence_by_hs_url\": {\n \"https://matrix.org\": false,\n \"https://matrix-client.matrix.org\": false\n },\n \"terms_and_conditions_links\": [\n {\n \"url\": \"https://element.io/privacy\",\n \"text\": \"Privacy Policy\"\n },\n {\n \"url\": \"https://element.io/cookie-policy\",\n \"text\": \"Cookie Policy\"\n }\n ],\n \"features\": {\n \"feature_video_rooms\": true,\n \"feature_rust_crypto\": true\n },\n \"element_call\": {\n \"url\": \"https://call.element.dev\"\n }\n}\n" + }, + { + "id": "net", + "type": "network", + "name": "matrix" + }, + { + "id": "homeserver", + "type": "container", + "name": "matrix", + "image": "matrixconduit/matrix-conduit@sha256:b0d24248e94f944ca49f90f10c429e3d65f4472bdde25661ecea9840134fb133", + "network": "matrix", + "env": { + "CONDUIT_CONFIG": "/etc/conduit/conduit.toml" + }, + "ports": [ + "6167" + ], + "volumes": [ + "${dir:db}:/var/lib/matrix-conduit", + "${dir:state}/conduit.toml:/etc/conduit/conduit.toml:ro" + ], + "restart-on": [ + "conduit-conf" + ] + }, + { + "id": "element", + "type": "container", + "name": "element-web", + "image": "vectorim/element-web@sha256:a8f415462ab8d2600a592ba1b92bea51efe5a4d10eb738aab9bed769f7099613", + "network": "matrix", + "ports": [ + "80" + ], + "volumes": [ + "${dir:state}/element.json:/app/config.json:ro" + ], + "restart-on": [ + "element-conf" + ] + } + ] +}