joplin-notes/joplin notion extension/Web Development/Extras/Tools/matrix homeserver.md
2026-11-04 00:33:23 +05:30

11 KiB

resource https://github.com/spantaleev/matrix-docker-ansible-deploy

matrix homeserver

some servers

  • synapse : standard one and feature rich but heavy

lightweight ones https://git.telodendria.org/jakubgencur/Telodendria, conduit,dendrite and https://github.com/heusalagroup/hghs, https://github.com/matrix-construct/tuwunel

trying tuwunel

  1. download release https://github.com/matrix-construct/tuwunel/releases/download/v1.5.1/v1.5.1-release-all-x86_64-v3-linux-gnu-tuwunel.zst
  2. executing it will work but first needed to be configured
  3. create a toml file say config.toml and use example from https://matrix-construct.github.io/tuwunel/configuration/examples.html#example-configuration (it acts as template). or config.toml

[global]

# The server_name is the pretty name of this server. It is used as a
# suffix for user and room IDs/aliases.
#
# See the docs for reverse proxying and delegation:
# https://tuwunel.chat/deploying/generic.html#setting-up-the-reverse-proxy
#
# Also see the `[global.well_known]` config section at the very bottom.
#
# Examples of delegation:
# - https://matrix.org/.well-known/matrix/server
# - https://matrix.org/.well-known/matrix/client
#
# YOU NEED TO EDIT THIS. THIS CANNOT BE CHANGED AFTER WITHOUT A DATABASE
# WIPE.
#
# example: "girlboss.ceo"
#
server_name = "muty.org"

# This is the only directory where tuwunel will save its data, including
# media. Note: this was previously "/var/lib/matrix-conduit".
#
database_path = "database"

allow_registration = true

# Enabling this setting opens registration to anyone without restrictions.
# This makes your server vulnerable to abuse
#
yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true

# by adding 0.0.0.0 it will not only be available for localhost but for devices sharing same wifi too
address = ["127.0.0.1", "::1","0.0.0.0"]

 

synapse https://element-hq.github.io/synapse/latest/setup/installation.html#installing-as-a-python-module-from-pypi

pip way after creating a folder and cd to it

python3 -m venv env # to create venv
source env/bin/activate  # to activate it
pip install --upgrade pip
pip install --upgrade setuptools
pip install matrix-synapse

configuration python -m synapse.app.homeserver \ --server-name my.domain.name \ --config-path homeserver.yaml \ --generate-config \ --report-stats=[yes|no]

starting it synctl start or for non daemon python3 -m synapse.app.homeserver -c homeserver.yaml

more configuration

enable_registration: true
enable_registration_without_verification: true
url_preview_enabled: true
url_preview_ip_range_blacklist: null

using postgresql instead of sqlite for production https://element-hq.github.io/synapse/latest/postgres.html#porting-from-sqlite Using Postgres - Synapse.pdf

  1. Make sure to install psycopg2 by source env/bin/activate && pip install psycopg2-binary

   

connecting with ngrok

The error you're seeing—"homeserver configuration found with is unusable"—typically comes from Element (or another Matrix client) when it discovers your homeserver's configuration (via .well-known or direct probing) but decides the setup is invalid or unreachable for some reason.

This is very common when using ngrok to expose a local Synapse server (especially on localhost:8008), because ngrok creates a temporary HTTPS URL, but several things break federation/client discovery.

Most likely causes with ngrok

  1. Your server_name in homeserver.yaml is still set to something like localhost, 127.0.0.1, or your local machine name (not the ngrok URL).

    • Synapse must know its public identity → server_name: your-ngrok-subdomain.ngrok-free.app (or whatever your ngrok URL is without https://).
    • Clients expect the homeserver to present itself consistently under that name.
  2. No .well-known/matrix/server and/or .well-known/matrix/client** delegation set up.

    • Modern clients (especially Element) strongly prefer or require delegation via these files when the base URL ≠ server_name.
    • With ngrok you almost always need them.
  3. Ngrok free tier limitations — the random/free URLs often cause strict clients to reject the certificate or see the setup as "unusable" because:

    • The domain doesn't match expectations
    • No proper TLS setup or mixed HTTP/HTTPS probing
    • Ngrok injects a page/captchas sometimes → breaks /.well-known requests
  4. You're entering the wrong URL in the client:

    • Don't enter http://localhost:8008
    • Don't enter https://xxxx.ngrok-free.app:8008 (ngrok already forwards to 8008)
    • Usually just enter https://xxxx.ngrok-free.app (or your custom ngrok domain)

Quick fix steps (most reliable for ngrok)

  1. Stop Synapse, edit homeserver.yaml:

    server_name: "abcd1234.ngrok-free.app"   # ← use your ACTUAL ngrok URL here (no https://, no port)
    
    # If you want federation later (optional but recommended)
    federation_domain_whitelist: []   # or leave commented
    
    # Make sure these are NOT forcing http or weird ports
    public_baseurl: https://abcd1234.ngrok-free.app/   # optional but helps
    

    → Restart Synapse

  2. Set up .well-known delegation (this is usually what fixes the "unusable" error):

    Create a simple static web server (or use Python's built-in one) on port 80 or 443 if you can, but since you're using ngrok for 8008, the easiest is:

    • Run a tiny HTTP server in a separate terminal (in a new folder):

      mkdir well-known
      cd well-known
      mkdir -p .well-known/matrix
      

      Create two files:

      .well-known/matrix/server:

      {
        "m.server": "abcd1234.ngrok-free.app:443"
      }
      

      .well-known/matrix/client:

      {
        "m.homeserver": {
          "base_url": "https://abcd1234.ngrok-free.app"
        }
      }
      
    • Start a simple server in that folder:

      python3 -m http.server 8080
      
    • Run a second ngrok tunnel just for this well-known:

      ngrok http 8080
      

      → Get a new ngrok URL, e.g. https://abcd-wellknown.ngrok-free.app

    • Then in your main homeserver.yaml add/change:

      serve_server_wellknown: false   # optional
      

      But actually tell clients to use the well-known domain as the homeserver URL.

    Better: use your main ngrok URL as server_name, and serve the .well-known files via Synapse itself (add to homeserver.yaml):

    additional_wellknown_roots:
      - path: /.well-known/matrix/server
        content: '{"m.server": "your-ngrok-url:443"}'
      - path: /.well-known/matrix/client
        content: '{"m.homeserver": {"base_url": "https://your-ngrok-url"}}'
    

    Restart Synapse → it will serve them directly.

  3. In Element (web/desktop/mobile):

    • Custom server / Edit → enter exactly https://your-ngrok-url (no port, no /)
    • It should discover the config and say something like "Homeserver configuration found with https://your-ngrok-url"
    • If it still says unusable → open browser dev tools (F12) → Network tab → look what request to /_matrix/client/versions or /.well-known fails and why (404, 502, cert error, etc.)

Even easier alternatives if ngrok keeps fighting you

  • Use a free static tunnel like bore.pub, pinggy.io, or localhost.run (sometimes behave better with Matrix)
  • Get a cheap domain + Cloudflare Tunnel (zero trust) — much more reliable for Synapse
  • Use Tailscale / Headscale + funnel — exposes localhost securely without public URL hassle

Test first with curl https://your-ngrok-url/_matrix/client/versions — should return JSON with "versions": [...].

If you share:

  • Your exact server_name: line
  • The full ngrok URL you're using
  • What exactly you enter in Element
  • The exact error message (including the part)

I can narrow it down further!

   

for converting to https for LAN IP

resource : https://medium.com/@antelle/how-to-generate-a-self-signed-ssl-certificate-for-an-ip-address-f0dd8dddf754 How to generate a self-signed SSL certificate for an IP address _ by Dimitri Witkowski _ Medium.pdf Self sign certificate way

  • create the following file named openssl.cnf. 192.168.1.50 is LAN IP

      [ req ]
      default_bits       = 2048
      distinguished_name = req_distinguished_name
      req_extensions     = req_ext
      prompt             = no
    
      [ req_distinguished_name ]
      C  = US
      ST = State
      L  = City
      O  = Local
      CN = 127.0.0.1
    
      [ req_ext ]
      subjectAltName = @alt_names
    
      [ alt_names ]
      IP.1 = 127.0.0.1
      DNS.1 = localhost
      IP.2 = 192.168.1.50
    
    
  • now using this configuration, generate certificate and private key openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt -config openssl.cnf -extensions req_ext

  • not finallly in homeserver.yaml add these cetificates and enable tls

    server_name: "muta.org"
      pid_file: /home/hpmi/Downloads/executables/synapse/homeserver.pid
    
      # 1. Add these two lines globally to define your certificate paths
      tls_certificate_path: "/home/hpmi/Downloads/executables/synapse/server.crt"
      tls_private_key_path: "/home/hpmi/Downloads/executables/synapse/server.key"
    
      listeners:
        - bind_addresses:
          - ::1
          - 0.0.0.0
          port: 8008
          resources:
          - compress: false
            names:
            - client
            - federation
          tls: true          # 2. Change this from false to true
          type: http
          x_forwarded: true
    
  • Now trust these certificates in client. in browser or maybe some apps there might be prompt to trust them so do that. in browser open the server LAN IP(not the client one) in tab and select 'accpet risk and continue'. in case of desktop like linux add them like this. add that crt file in this location /usr/local/share/ca-certificates/ and then run command for updating sudo update-ca-certificates   for a full ca one use openssl req -x509 -newkey rsa:4048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost" -addext "basicConstraints=critical,CA:TRUE"

    with https there can be issues with client which give no proper option to allow self signed certifciates so best way is to use both and use http where it can be used in homeserver.yaml

    listeners:
    # HTTPS
    - port: 8448
      bind_addresses:
        - "0.0.0.0"
        - "::1"
      type: http
      tls: true
      x_forwarded: false
      resources:
        - names:
            - client
            - federation
          compress: false
    
    # HTTP
    - port: 8008
      bind_addresses:
        - "0.0.0.0"
        - "::1"
      type: http
      tls: false
      x_forwarded: false
      resources:
        - names:
            - client
            - federation
          compress: false
    

Client

Nheko

for managing multiple accounts use profile

flatpak run im.nheko.Nheko -p default or flatpak run im.nheko.Nheko if not flatpak and directly installed nheko -p default for something other than default nheko -p work