Matrix and Element: Matrix Web UI

Published: Nov 14, 2023 by Isaac Johnson

Element is already the client I use in Android. However, they have Clients for all OSes, including a self-hosted one that includes running in Kubernetes.

Element Web

I’ll need an A record for NGinx and TLS, so let’s take care of that first

builder@DESKTOP-QADGF36:~/Workspaces/jekyll-blog$ cat r53-element.json
{
    "Comment": "CREATE element fb.s A record ",
    "Changes": [
      {
        "Action": "CREATE",
        "ResourceRecordSet": {
          "Name": "element.freshbrewed.science",
          "Type": "A",
          "TTL": 300,
          "ResourceRecords": [
            {
              "Value": "75.73.224.240"
            }
          ]
        }
      }
    ]
  }
builder@DESKTOP-QADGF36:~/Workspaces/jekyll-blog$ aws route53 change-resource-record-sets --hosted-zone-id Z39E8QFU0F9PZP --change-batch file://r53-element.json
{
    "ChangeInfo": {
        "Id": "/change/C09728111XHO3ELZ2CVRY",
        "Status": "PENDING",
        "SubmittedAt": "2023-11-04T13:25:09.439Z",
        "Comment": "CREATE element fb.s A record "
    }
}

I can then create a namespace, configmap and deployment in one fell swoop. I used the exmaple here.

---
apiVersion: v1
kind: Namespace
metadata:
  name: element-web
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: element-config
  namespace: element-web
data:
  config.json: |
    {
        "default_server_config": {
            "m.homeserver": {
                "base_url": "https://matrix.freshbrewed.science",
                "server_name": "matrix.freshbrewed.science"
            },
            "m.identity_server": {
                "base_url": "https://vector.im"
            }
        },
        "disable_custom_urls": false,
        "disable_guests": false,
        "disable_login_language_selector": false,
        "disable_3pid_login": false,
        "brand": "Element",
        "integrations_ui_url": "https://scalar.vector.im/",
        "integrations_rest_url": "https://scalar.vector.im/api",
        "integrations_widgets_urls": [
                "https://scalar.vector.im/_matrix/integrations/v1",
                "https://scalar.vector.im/api",
                "https://scalar-staging.vector.im/_matrix/integrations/v1",
                "https://scalar-staging.vector.im/api",
                "https://scalar-staging.riot.im/scalar/api"
        ],
        "bug_report_endpoint_url": "https://element.io/bugreports/submit",
        "defaultCountryCode": "GB",
        "show_labs_settings": false,
        "features": { },
        "default_federate": true,
        "default_theme": "light",
        "room_directory": {
            "servers": [
                    "matrix.org"
            ]
        },
        "enable_presence_by_hs_url": {
            "https://matrix.org": false,
            "https://matrix-client.matrix.org": false
        },
        "setting_defaults": {
            "breadcrumbs": true
        },
        "jitsi": {
            "preferred_domain": "meet.element.io"
        }
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: element
  namespace: element-web
spec:
  selector:
    matchLabels:
      app: element
  replicas: 1
  template:
    metadata:
      labels:
        app: element
    spec:
      containers:
      - name: element
        image: vectorim/element-web:latest
        volumeMounts:
        - name: config-volume
          mountPath: /app/config.json
          subPath: config.json
        ports:
        - containerPort: 80
          name: element
          protocol: TCP
        readinessProbe:
            httpGet:
                path: /
                port: element
            initialDelaySeconds: 2
            periodSeconds: 3
        livenessProbe:
            httpGet:
                path: /
                port: element
            initialDelaySeconds: 10
            periodSeconds: 10
      volumes:
      - name: config-volume
        configMap:
          name: element-config
---
apiVersion: v1
kind: Service
metadata:
  name: elementsvc
  namespace: element-web
spec:
  selector:
    app: element
  ports:
    - name: default
      protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
  labels:
    app.kubernetes.io/instance: elementingress
  name: elementingress
  namespace: element-web
spec:
  rules:
  - host: element.freshbrewed.science
    http:
      paths:
      - backend:
          service:
            name: elementsvc
            port:
              number: 80
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - element.freshbrewed.science
    secretName: element-tls
---

I’ll now apply it

$ kubectl apply -f elementweb.yaml
namespace/element-web created
configmap/element-config created
deployment.apps/element created
service/element created
ingress.networking.k8s.io/element created

I can now see the app running

/content/images/2023/11/element-01.png

One thing I love is that when I sign in

/content/images/2023/11/element-02.png

There is a back and forth verification (similar to keybase) that requires me to auth on another device

/content/images/2023/11/element-03.png

Once I scan a QR and confirm, then I confirm similar images

/content/images/2023/11/element-04.png

and I’m then allowed in.

/content/images/2023/11/element-05.png

I now have a “front door” for Matrix Synapse running in the same cluster.

Pricing

Element, while fully Open-Source, does have managed offerings as well. For those looking for hosted option, they have a “Business” tier at $5/user/month, an “Enterprise” at $10/user/month and a “Sovereign” version that would add in AV, a branded mobile app and briding to other communications systems

/content/images/2023/11/element-06.png

https://github.com/vector-im/element-web

Matrix Chat Element

Have something to add? Feedback? You can use the feedback form

Isaac Johnson

Isaac Johnson

Cloud Solutions Architect

Isaac is a CSA and DevOps engineer who focuses on cloud migrations and devops processes. He also is a dad to three wonderful daughters (hence the references to Princess King sprinkled throughout the blog).

Theme built by C.S. Rhymes