home.social

#synapse — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #synapse, aggregated by home.social.

fetched live
  1. Run your own Synapse server including Element Call and Element Web

    blog.sengotta.net/run-your-own

    Once again, this is mainly a post for myself, so that I do not forget everything the next time I have to set up a Matrix server. This time it is about Synapse, the reference server for the Matrix protocol.

    If you have found this page, you probably already know what Synapse and the Matrix protocol are. Besides normal textchat, it can also handle voice and video calls and many other things. The Matrix protocol is very powerful. Unfortunately, this also makes it very complicated. As a result, there are still not many serious alternatives to Synapse or the Element clients if you want to use the full feature set.

    So why am I spending time on this? In everyday life I mainly use Signal. In my opinion it is an excellent service, although some people will probably disagree immediately. However, it is a centralised service, it depends on a mobile phone number, it is within Donald Trump’s jurisdiction, and if the planned chat control ever becomes reality, Signal has already said that they might leave the European market.

    For me, my own Synapse server is therefore a kind of emergency plan for communication. It is also very useful for smart home notifications, privacy-related applications and similar things. Matrix is designed to be decentralised, so it is a bit unfortunate that so many users have made matrix.org their permanent home.

    Setting up a Synapse server, including the backend for Element Call, is unfortunately not straightforward. That is why I decided to collect everything in one place. This is not a step-by-step tutorial explaining every single line. At some point you still have to think for yourself. The guide is also based on my own setup, namely Docker with a native nginx reverse proxy. Your setup may be different, but perhaps this can still serve as a useful reference. I had to collect the required information from many different sources myself. Therefore, I will include all relevant configuration files so that you can compare them with your own.

    Originally I wanted to upload the files to Codeberg, but apparently the service is currently having some problems.

    At the end, you should have a working Synapse server including Element Web and Element Call.

    Requirements:

    1. Internet facing Linux server with docker, docker compose and nginx. If you use a firewall dont forget to confgigure it correctly
    2. Two Domains i use matrix.example.eu and matrixrtc.example.eu, you have to replace them on any accurance
    3. TLS Certs for both domains

    Folder structure

    The first step is to create a suitable folder structure. In my case, every container together with its configuration files has its own directory below /opt. For my Matrix server it looks like this.

    opt
    └── matrix
        ├── elementweb
        ├── livekit
        ├── postgres
        ├── synapse
        └── docker-compose.yaml

    You do not need to create the docker-compose.yaml file yet.

    Generate homeserver.yaml

    Once the directory structure is ready, let Synapse generate the initial homeserver.yaml together with all required keys and secrets. You can do this with the following command. Afterwards you will find the generated homeserver.yaml inside the synapse directory. If your directory layout is different, simply adjust the command accordingly.

    docker run -it --rm \
      -v /opt/matrix/synapse:/data \
      -e SYNAPSE_SERVER_NAME=matrix.example.eu \
      -e SYNAPSE_REPORT_STATS=no \
      matrixdotorg/synapse:latest generate

    Editing homeserver.yaml

    Now open the generated homeserver.yaml and apply the changes shown in my example. Please do not simply copy and paste everything, otherwise your own keys and secrets will be overwritten. Go through the file line by line. If you are unsure about a setting, have a look at the Synapse documentation. As already mentioned, you still have to think for yourself from time to time. Also make sure to choose a proper password for the PostgreSQL database. You will need exactly the same password later in your Docker Compose configuration.

    # Configuration file for Synapse.
    #
    # This is a YAML file: see [1] for a quick introduction. Note in particular
    # that *indentation is important*: all the elements of a list or dictionary
    # should have the same indentation.
    #
    # [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
    #
    # For more information on how to configure Synapse, including a complete accounting of
    # each option, go to docs/usage/configuration/config_documentation.md or
    # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html
    server_name: "matrix.example.eu"
    pid_file: /data/homeserver.pid
    listeners:
      - port: 8008
        resources:
        - compress: false
          names:
          - client
          - federation
        tls: false
        type: http
        x_forwarded: true
    database:
      name: psycopg2
      args:
        user: synapse
        password: mySuperSecretPassword
        database: synapse
        host: db
        port: 5432
        cp_min: 5
        cp_max: 10
    log_config: "/data/matrix.example.eu.log.config"
    media_store_path: /data/media_store
    max_upload_size: 50M
    enable_registration: false
    enable_registration_without_verification: false
    registration_shared_secret: "AutoGenerated"
    # Retention policy
    retention:
      enabled: true
      default_policy:
        min_lifetime: 1d
        max_lifetime: 365d
    url_preview_enabled: true
    url_preview_ip_range_blacklist:
      - '127.0.0.0/8'
      - '10.0.0.0/8'
      - '172.16.0.0/12'
      - '192.168.0.0/16'
    report_stats: false
    macaroon_secret_key: "AutoGenerated"
    form_secret: "AutoGenerated"
    signing_key_path: "/data/matrix.example.eu.signing.key"
    trusted_key_servers:
      - server_name: "matrix.org"
    experimental_features:
      # MSC3266: Room summary API. Used for knocking over federation
      msc3266_enabled: true
      # MSC4222: needed for syncv2 state_after. This allows clients to
      # correctly track the state of the room.
      msc4222_enabled: true
      # MSC4140: Delayed events are required for proper call participation signalling. If disabled it is very likely that you end up with stuck calls in Matrix rooms
      msc4140_enabled: true
    
    # The maximum allowed duration by which sent events can be delayed, as
    # per MSC4140.
    max_event_delay_duration: 24h
    
    rc_message:
      # This needs to match at least e2ee key sharing frequency plus a bit of headroom
      # Note key sharing events are bursty
      per_second: 0.5
      burst_count: 30
      # This needs to match at least the heart-beat frequency plus a bit of headroom
      # Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
    rc_delayed_event_mgmt:
      per_second: 1
      burst_count: 20

    Edit docker-compose.yaml

    Next, create the docker-compose.yaml file. The file is already commented, so it should be reasonably clear which values need to be changed. The most important ones are the database password as well as the key and secret for LiveKit. The comments also explain how to generate these values.

    services:
      synapse:
        image: matrixdotorg/synapse:latest
        container_name: synapse
        restart: unless-stopped
        volumes:
          - ./synapse:/data
        ports:
          - "127.0.0.1:8008:8008"   # Bind to loopback
        depends_on:
          - db
    
      db:
        image: postgres:16-alpine
        container_name: synapse-db
        restart: unless-stopped
        environment:
          POSTGRES_USER: synapse
          POSTGRES_PASSWORD: CHANGEME #also in synapse/homeserver.yaml
          POSTGRES_DB: synapse
          POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
        volumes:
          - ./postgres:/var/lib/postgresql/data
        ports:
          - "127.0.0.1:5432:5432"
    
      auth-service:
        image: ghcr.io/element-hq/lk-jwt-service:latest
        container_name: element-call-jwt
        hostname: auth-server
        environment:
          - LIVEKIT_JWT_PORT=8080
          - LIVEKIT_URL=https://matrixrtc.example.eu/livekit/sfu #CHANGEME
          - LIVEKIT_KEY=CHANGEME # use tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 64 to generate key / also change in livekit/config.yaml
          - LIVEKIT_SECRET=CHANGEME # use tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 64 to generate key / also change in livekit/config.yaml
          - LIVEKIT_FULL_ACCESS_HOMESERVERS=matrix.example.eu
        restart: unless-stopped
        ports:
          - 127.0.0.1:8070:8080 #Change 8070 to whichever port you want JWT to be available on locally
    
      livekit:
        image: livekit/livekit-server:latest
        container_name: element-call-livekit
        command: --config /etc/livekit.yaml
        ports:
          - 127.0.0.1:7880:7880/tcp
          - 7881:7881/tcp
          - 50100-50200:50100-50200/udp
        restart: unless-stopped
        volumes:
          - ./livekit/config.yaml:/etc/livekit.yaml:ro
    
      element-web:
        image: vectorim/element-web:latest
        restart: unless-stopped
        ports:
          - "127.0.0.1:8009:80"
        healthcheck:
          test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:80/version || exit 1"]
          start_period: "5s"
          interval: "15s"
          timeout: "5s"
        volumes:
          - ./element-web/config.json:/app/config.json
        depends_on:
          - synapse

    Livekit configuration

    The next file to edit is config.yaml inside the livekit directory. Here you mainly have to adjust the external IP address of your server and insert the LiveKit key and secret you generated before. By the way, I recently came across an interesting article (https://sspaeth.de/2026/04/matrix-voip-and-livekit/) explaining that, in most cases, you will not need a TURN server at all—neither the one built into LiveKit nor a separate CoTURN installation. One less service to maintain is rarely a bad thing.

    port: 7880
    bind_addresses:
      - "0.0.0.0"
    rtc:
      tcp_port: 7881
      port_range_start: 50100
      port_range_end: 50200
      use_external_ip: true
      node_ip: Externe IP eures Servers
    room:
      auto_create: false
    logging:
      level: info
    turn:
      enabled: false
      domain: localhost
      cert_file: ""
      key_file: ""
      tls_port: 5349
      udp_port: 443
      external_tls: true
    keys:
      LIVEKIT_KEY: LIVEKIT_SECRET # Values from your docker compose, mind the space!

    Element Web configuration

    The last configuration file is the JSON configuration for Element Web, assuming you want to use it. Once again, you mainly need to adjust the URLs and a few other values so that they match your own setup.

    {
        "default_server_config": {
            "m.homeserver": {
                "base_url": "https://matrix.example.eu",
                "server_name": "matrix.example.eu"
            },
            "m.identity_server": {
                "base_url": "https://vector.im"
            }
        },
        "disable_custom_urls": false,
        "disable_guests": false,
        "disable_login_language_selector": false,
        "disable_3pid_login": false,
        "force_verification": false,
        "brand": "Element",
        "default_widget_container_height": 280,
        "default_country_code": "DE",
        "show_labs_settings": false,
        "features": {
            "feature_video_rooms": true,
            "feature_group_calls": true,
            "feature_element_call_video_rooms": true,
            "feature_oidc_native_flow": true
        },
        "default_federate": true,
        "default_theme": "light",
        "room_directory": {
            "servers": ["https://matrix.example.eu"]
        },
        "setting_defaults": {
            "breadcrumbs": true
        },
        "element_call": {
            "url": "https://matrixrtc.example.eu"
        },
        "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
    }

    Nginx configuration

    To make your Synapse server reachable from the Internet and allow federation with other Matrix servers, you also need a suitable reverse proxy. In my case this is nginx. You can use the following configuration as a starting point. Of course, you have to replace the domain names and the paths to your TLS certificates with your own values.

    # HTTPS redirect
    server {
        listen 80;
        listen [::]:80;
        server_name matrix.example.eu;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # Client API
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name matrix.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrix.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrix.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
    
        client_max_body_size 50M;
    
        # Well-known for Client Configuration
        location /.well-known/matrix/client {
            return 200 '{"m.homeserver": {"base_url": "https://matrix.example.eu"}, "m.identity_server": {"base_url": "https://vector.im"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://matrixrtc.example.eu/livekit/jwt"}]}';
            default_type application/json;
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, OPTIONS';
        }
    
        # Well-known for federation
        location /.well-known/matrix/server {
            return 200 '{"m.server":"matrix.example.eu:8448"}';
            default_type application/json;
        }
    
        location / {
            proxy_pass http://localhost:8009;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    
        # Forward to dockerized Synapse
        location ~* ^(\/_matrix|\/_synapse\/client) {
            proxy_pass         http://localhost:8008;
            proxy_set_header   X-Forwarded-For $remote_addr;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
    
            proxy_read_timeout    600;
            proxy_connect_timeout 600;
            proxy_send_timeout    600;
        }
    }
    
    # Federation Port 8448
    server {
        listen 8448 ssl http2;
        listen [::]:8448 ssl http2;
        server_name matrix.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrix.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrix.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
        client_max_body_size 50M;
    
    
        location / {
            proxy_pass         http://localhost:8008;
            proxy_set_header   X-Forwarded-For $remote_addr;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
        }
    }
    # HTTPS redirect
    server {
        listen 80;
        listen [::]:80;
        server_name matrixrtc.example.eu;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # HTTPS Client API
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name matrixrtc.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrixrtc.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrixrtc.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
    location ^~ /livekit/jwt/ {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    
          # MatrixRTC Authorization Service running at port 8080
          proxy_pass http://localhost:8070/;
        }
    
        location ^~ /livekit/sfu/ {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    
          proxy_send_timeout 120;
          proxy_read_timeout 120;
          proxy_buffering off;
    
          proxy_set_header Accept-Encoding gzip;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
    
    
          # LiveKit SFU websocket connection running at port 7880
          proxy_pass http://localhost:7880/;
        }
    }
    
    

    After that, create the appropriate symbolic link so that nginx knows about the new configuration and reload the service. Danach konnt Ihr wieder in den Ordner /opt/matrix wechseln und den Synapse Server starten:

    Start Synapse Server

    Once this is done, change back to your /opt/matrix directory and start the Synapse server.

    docker compose up

    For the first start I deliberately left out the detached mode. This way you can watch the log output and also see when the database initialisation has finished.

    Creating users

    Since registration is disabled, you have to create users from the command line. The first user can also be made an administrator straight away. For any additional users, simply replace –admin with –no-admin.

    docker exec -it synapse register_new_matrix_user \
      http://localhost:8008 \
      -c /data/homeserver.yaml \
      -u meinErsterUser \
      -p SuperSicheresPasswort \
      --admin

    At this point your own Synapse server should be running and should also be able to federate with other Matrix servers. If you notice mistakes in the configuration or have constructive suggestions, feel free to leave a comment. Setting up a complete Matrix environment is quite complex, and there is no single guide that works perfectly for every setup (and this one isnt it either).

    Still, I hope this article encourages some people to set up their own Matrix server. Every additional independent server makes the Matrix ecosystem a little more resilient, and that can only be a good thing.

    #element #linux #livekit #matrix #opensource #selfhosting #synapse #unplugbigtech #unplugtrump @bjoern
  2. Run your own Synapse server including Element Call and Element Web

    blog.sengotta.net/run-your-own

    Once again, this is mainly a post for myself, so that I do not forget everything the next time I have to set up a Matrix server. This time it is about Synapse, the reference server for the Matrix protocol.

    If you have found this page, you probably already know what Synapse and the Matrix protocol are. Besides normal textchat, it can also handle voice and video calls and many other things. The Matrix protocol is very powerful. Unfortunately, this also makes it very complicated. As a result, there are still not many serious alternatives to Synapse or the Element clients if you want to use the full feature set.

    So why am I spending time on this? In everyday life I mainly use Signal. In my opinion it is an excellent service, although some people will probably disagree immediately. However, it is a centralised service, it depends on a mobile phone number, it is within Donald Trump’s jurisdiction, and if the planned chat control ever becomes reality, Signal has already said that they might leave the European market.

    For me, my own Synapse server is therefore a kind of emergency plan for communication. It is also very useful for smart home notifications, privacy-related applications and similar things. Matrix is designed to be decentralised, so it is a bit unfortunate that so many users have made matrix.org their permanent home.

    Setting up a Synapse server, including the backend for Element Call, is unfortunately not straightforward. That is why I decided to collect everything in one place. This is not a step-by-step tutorial explaining every single line. At some point you still have to think for yourself. The guide is also based on my own setup, namely Docker with a native nginx reverse proxy. Your setup may be different, but perhaps this can still serve as a useful reference. I had to collect the required information from many different sources myself. Therefore, I will include all relevant configuration files so that you can compare them with your own.

    Originally I wanted to upload the files to Codeberg, but apparently the service is currently having some problems.

    At the end, you should have a working Synapse server including Element Web and Element Call.

    Requirements:

    1. Internet facing Linux server with docker, docker compose and nginx. If you use a firewall dont forget to confgigure it correctly
    2. Two Domains i use matrix.example.eu and matrixrtc.example.eu, you have to replace them on any accurance
    3. TLS Certs for both domains

    Folder structure

    The first step is to create a suitable folder structure. In my case, every container together with its configuration files has its own directory below /opt. For my Matrix server it looks like this.

    opt
    └── matrix
        ├── elementweb
        ├── livekit
        ├── postgres
        ├── synapse
        └── docker-compose.yaml

    You do not need to create the docker-compose.yaml file yet.

    Generate homeserver.yaml

    Once the directory structure is ready, let Synapse generate the initial homeserver.yaml together with all required keys and secrets. You can do this with the following command. Afterwards you will find the generated homeserver.yaml inside the synapse directory. If your directory layout is different, simply adjust the command accordingly.

    docker run -it --rm \
      -v /opt/matrix/synapse:/data \
      -e SYNAPSE_SERVER_NAME=matrix.example.eu \
      -e SYNAPSE_REPORT_STATS=no \
      matrixdotorg/synapse:latest generate

    Editing homeserver.yaml

    Now open the generated homeserver.yaml and apply the changes shown in my example. Please do not simply copy and paste everything, otherwise your own keys and secrets will be overwritten. Go through the file line by line. If you are unsure about a setting, have a look at the Synapse documentation. As already mentioned, you still have to think for yourself from time to time. Also make sure to choose a proper password for the PostgreSQL database. You will need exactly the same password later in your Docker Compose configuration.

    # Configuration file for Synapse.
    #
    # This is a YAML file: see [1] for a quick introduction. Note in particular
    # that *indentation is important*: all the elements of a list or dictionary
    # should have the same indentation.
    #
    # [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
    #
    # For more information on how to configure Synapse, including a complete accounting of
    # each option, go to docs/usage/configuration/config_documentation.md or
    # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html
    server_name: "matrix.example.eu"
    pid_file: /data/homeserver.pid
    listeners:
      - port: 8008
        resources:
        - compress: false
          names:
          - client
          - federation
        tls: false
        type: http
        x_forwarded: true
    database:
      name: psycopg2
      args:
        user: synapse
        password: mySuperSecretPassword
        database: synapse
        host: db
        port: 5432
        cp_min: 5
        cp_max: 10
    log_config: "/data/matrix.example.eu.log.config"
    media_store_path: /data/media_store
    max_upload_size: 50M
    enable_registration: false
    enable_registration_without_verification: false
    registration_shared_secret: "AutoGenerated"
    # Retention policy
    retention:
      enabled: true
      default_policy:
        min_lifetime: 1d
        max_lifetime: 365d
    url_preview_enabled: true
    url_preview_ip_range_blacklist:
      - '127.0.0.0/8'
      - '10.0.0.0/8'
      - '172.16.0.0/12'
      - '192.168.0.0/16'
    report_stats: false
    macaroon_secret_key: "AutoGenerated"
    form_secret: "AutoGenerated"
    signing_key_path: "/data/matrix.example.eu.signing.key"
    trusted_key_servers:
      - server_name: "matrix.org"
    experimental_features:
      # MSC3266: Room summary API. Used for knocking over federation
      msc3266_enabled: true
      # MSC4222: needed for syncv2 state_after. This allows clients to
      # correctly track the state of the room.
      msc4222_enabled: true
      # MSC4140: Delayed events are required for proper call participation signalling. If disabled it is very likely that you end up with stuck calls in Matrix rooms
      msc4140_enabled: true
    
    # The maximum allowed duration by which sent events can be delayed, as
    # per MSC4140.
    max_event_delay_duration: 24h
    
    rc_message:
      # This needs to match at least e2ee key sharing frequency plus a bit of headroom
      # Note key sharing events are bursty
      per_second: 0.5
      burst_count: 30
      # This needs to match at least the heart-beat frequency plus a bit of headroom
      # Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
    rc_delayed_event_mgmt:
      per_second: 1
      burst_count: 20

    Edit docker-compose.yaml

    Next, create the docker-compose.yaml file. The file is already commented, so it should be reasonably clear which values need to be changed. The most important ones are the database password as well as the key and secret for LiveKit. The comments also explain how to generate these values.

    services:
      synapse:
        image: matrixdotorg/synapse:latest
        container_name: synapse
        restart: unless-stopped
        volumes:
          - ./synapse:/data
        ports:
          - "127.0.0.1:8008:8008"   # Bind to loopback
        depends_on:
          - db
    
      db:
        image: postgres:16-alpine
        container_name: synapse-db
        restart: unless-stopped
        environment:
          POSTGRES_USER: synapse
          POSTGRES_PASSWORD: CHANGEME #also in synapse/homeserver.yaml
          POSTGRES_DB: synapse
          POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
        volumes:
          - ./postgres:/var/lib/postgresql/data
        ports:
          - "127.0.0.1:5432:5432"
    
      auth-service:
        image: ghcr.io/element-hq/lk-jwt-service:latest
        container_name: element-call-jwt
        hostname: auth-server
        environment:
          - LIVEKIT_JWT_PORT=8080
          - LIVEKIT_URL=https://matrixrtc.example.eu/livekit/sfu #CHANGEME
          - LIVEKIT_KEY=CHANGEME # use tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 64 to generate key / also change in livekit/config.yaml
          - LIVEKIT_SECRET=CHANGEME # use tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 64 to generate key / also change in livekit/config.yaml
          - LIVEKIT_FULL_ACCESS_HOMESERVERS=matrix.example.eu
        restart: unless-stopped
        ports:
          - 127.0.0.1:8070:8080 #Change 8070 to whichever port you want JWT to be available on locally
    
      livekit:
        image: livekit/livekit-server:latest
        container_name: element-call-livekit
        command: --config /etc/livekit.yaml
        ports:
          - 127.0.0.1:7880:7880/tcp
          - 7881:7881/tcp
          - 50100-50200:50100-50200/udp
        restart: unless-stopped
        volumes:
          - ./livekit/config.yaml:/etc/livekit.yaml:ro
    
      element-web:
        image: vectorim/element-web:latest
        restart: unless-stopped
        ports:
          - "127.0.0.1:8009:80"
        healthcheck:
          test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:80/version || exit 1"]
          start_period: "5s"
          interval: "15s"
          timeout: "5s"
        volumes:
          - ./element-web/config.json:/app/config.json
        depends_on:
          - synapse

    Livekit configuration

    The next file to edit is config.yaml inside the livekit directory. Here you mainly have to adjust the external IP address of your server and insert the LiveKit key and secret you generated before. By the way, I recently came across an interesting article (https://sspaeth.de/2026/04/matrix-voip-and-livekit/) explaining that, in most cases, you will not need a TURN server at all—neither the one built into LiveKit nor a separate CoTURN installation. One less service to maintain is rarely a bad thing.

    port: 7880
    bind_addresses:
      - "0.0.0.0"
    rtc:
      tcp_port: 7881
      port_range_start: 50100
      port_range_end: 50200
      use_external_ip: true
      node_ip: Externe IP eures Servers
    room:
      auto_create: false
    logging:
      level: info
    turn:
      enabled: false
      domain: localhost
      cert_file: ""
      key_file: ""
      tls_port: 5349
      udp_port: 443
      external_tls: true
    keys:
      LIVEKIT_KEY: LIVEKIT_SECRET # Values from your docker compose, mind the space!

    Element Web configuration

    The last configuration file is the JSON configuration for Element Web, assuming you want to use it. Once again, you mainly need to adjust the URLs and a few other values so that they match your own setup.

    {
        "default_server_config": {
            "m.homeserver": {
                "base_url": "https://matrix.example.eu",
                "server_name": "matrix.example.eu"
            },
            "m.identity_server": {
                "base_url": "https://vector.im"
            }
        },
        "disable_custom_urls": false,
        "disable_guests": false,
        "disable_login_language_selector": false,
        "disable_3pid_login": false,
        "force_verification": false,
        "brand": "Element",
        "default_widget_container_height": 280,
        "default_country_code": "DE",
        "show_labs_settings": false,
        "features": {
            "feature_video_rooms": true,
            "feature_group_calls": true,
            "feature_element_call_video_rooms": true,
            "feature_oidc_native_flow": true
        },
        "default_federate": true,
        "default_theme": "light",
        "room_directory": {
            "servers": ["https://matrix.example.eu"]
        },
        "setting_defaults": {
            "breadcrumbs": true
        },
        "element_call": {
            "url": "https://matrixrtc.example.eu"
        },
        "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
    }

    Nginx configuration

    To make your Synapse server reachable from the Internet and allow federation with other Matrix servers, you also need a suitable reverse proxy. In my case this is nginx. You can use the following configuration as a starting point. Of course, you have to replace the domain names and the paths to your TLS certificates with your own values.

    # HTTPS redirect
    server {
        listen 80;
        listen [::]:80;
        server_name matrix.example.eu;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # Client API
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name matrix.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrix.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrix.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
    
        client_max_body_size 50M;
    
        # Well-known for Client Configuration
        location /.well-known/matrix/client {
            return 200 '{"m.homeserver": {"base_url": "https://matrix.example.eu"}, "m.identity_server": {"base_url": "https://vector.im"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://matrixrtc.example.eu/livekit/jwt"}]}';
            default_type application/json;
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, OPTIONS';
        }
    
        # Well-known for federation
        location /.well-known/matrix/server {
            return 200 '{"m.server":"matrix.example.eu:8448"}';
            default_type application/json;
        }
    
        location / {
            proxy_pass http://localhost:8009;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    
        # Forward to dockerized Synapse
        location ~* ^(\/_matrix|\/_synapse\/client) {
            proxy_pass         http://localhost:8008;
            proxy_set_header   X-Forwarded-For $remote_addr;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
    
            proxy_read_timeout    600;
            proxy_connect_timeout 600;
            proxy_send_timeout    600;
        }
    }
    
    # Federation Port 8448
    server {
        listen 8448 ssl http2;
        listen [::]:8448 ssl http2;
        server_name matrix.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrix.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrix.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
        client_max_body_size 50M;
    
    
        location / {
            proxy_pass         http://localhost:8008;
            proxy_set_header   X-Forwarded-For $remote_addr;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
        }
    }
    # HTTPS redirect
    server {
        listen 80;
        listen [::]:80;
        server_name matrixrtc.example.eu;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # HTTPS Client API
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name matrixrtc.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrixrtc.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrixrtc.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
    location ^~ /livekit/jwt/ {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    
          # MatrixRTC Authorization Service running at port 8080
          proxy_pass http://localhost:8070/;
        }
    
        location ^~ /livekit/sfu/ {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    
          proxy_send_timeout 120;
          proxy_read_timeout 120;
          proxy_buffering off;
    
          proxy_set_header Accept-Encoding gzip;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
    
    
          # LiveKit SFU websocket connection running at port 7880
          proxy_pass http://localhost:7880/;
        }
    }
    
    

    After that, create the appropriate symbolic link so that nginx knows about the new configuration and reload the service. Danach konnt Ihr wieder in den Ordner /opt/matrix wechseln und den Synapse Server starten:

    Start Synapse Server

    Once this is done, change back to your /opt/matrix directory and start the Synapse server.

    docker compose up

    For the first start I deliberately left out the detached mode. This way you can watch the log output and also see when the database initialisation has finished.

    Creating users

    Since registration is disabled, you have to create users from the command line. The first user can also be made an administrator straight away. For any additional users, simply replace –admin with –no-admin.

    docker exec -it synapse register_new_matrix_user \
      http://localhost:8008 \
      -c /data/homeserver.yaml \
      -u meinErsterUser \
      -p SuperSicheresPasswort \
      --admin

    At this point your own Synapse server should be running and should also be able to federate with other Matrix servers. If you notice mistakes in the configuration or have constructive suggestions, feel free to leave a comment. Setting up a complete Matrix environment is quite complex, and there is no single guide that works perfectly for every setup (and this one isnt it either).

    Still, I hope this article encourages some people to set up their own Matrix server. Every additional independent server makes the Matrix ecosystem a little more resilient, and that can only be a good thing.

    #element #linux #livekit #matrix #opensource #selfhosting #synapse #unplugbigtech #unplugtrump @bjoern
  3. Eigenen Synapse Server für das Matrix Protokoll betreiben inklusive Element Call

    blog.sengotta.net/eigenen-syna

    Mal wieder ein Beitrag der vor allem mir als Gedankenstütze dienen soll. Und zwar geht es diesmal um Synapse, dem Referenzserver für das Matrix Protokoll.

    Wer hier gelandet ist wird sicher schon wissen was Synapse bzw. das Matrix Protokoll ist. Über diesen Server kann man vor allem chatten aber auch Video- und Audioanrufe abwickeln und noch vieles mehr. Das Matrix Protokoll ist extrem mächtig. Das ist nicht immer ein Vorteil, denn es zu implementieren ist somit auch extrem schwer. Das führt auch dazu das es bisher eigentlich kaum eine ernst zunehmende Alternative zu Synapse oder den Element Clients gibt wenn man den vollen Funktionsumfang nutzen möchte.

    Aber warum mach ich mir die Arbeit. Naja im Alltag nutze ich überwiegend Signal, was meiner Meinung nach ein super Dienst ist, auch wenn hier manche Leute jetzt wieder Schnappatmung kriegen. Aber dieser Dienst ist halt zentralisiert, an eine Mobilfunknummer gebunden, liegt im Machtbereich von Donald Trump und falls die Chatkontrolle kommt dann hat man auch schon angedroht sich aus dem europäischen Markt zurück zu ziehen.

    Mein eigener Synapse Server ist also mein Plan B in Sachen Kommunikation, ausserdem ist so eine Chatplattform auch ganz praktisch in Bezug auf Smarthome Benachrichtigungen, Datenschutz und Co. Des Weiteren ist Matrix als dezentrales System gedacht, von daher ist es geradezu traurig bis gefährlich wie viele User dieses Ökosystems Ihr Zuhause auf der Hauptinstanz matrix.org haben.

    Leider ist das Setup eines Synapse Servers inkl. dem Backend für Element Call nicht trivial, deswegen habe ich das hier mal zusammengefasst. Aber nein das hier ist jetzt keine Anleitung wo ich jedes Fitzelchen kommentiere etc. Teilweise muss man auch das eigene Hirn noch einschalten. Ausserdem ist das ganze an mein spezifisches Setup (Docker mit nativ installiertem nginx als reverse Proxy) angepasst. So oder so ist es ggf. eine Inspiration für euer eigenes Setup. Auch ich musste mir die Infos an etlichen Stellen zusammensuchen. Ich werde hier die einzelnen Config Dateien in den Beitrag einbetten so das Ihr nachschauen könnt was Ihr ändern müsst.

    Eigentlich wollte ich Sie auf Codeberg laden aber der Dienst kämpft wohl gerade mit Problemen.

    Am Ende solltet Ihr einen Synapse Server inkl. Element Web und Element Call am laufen haben.

    Vorraussetzungen:

    1. ein aus dem Internet erreichbarer Linux Server mit Docker, Docker compose und nginx. Falls Ihr eine Firewall einsetzt denkt daran diese entsprechend einzurichten und die notwendigen Ports freizugeben
    2. Zwei Domains, ich nutze im Beispiel matrix.example.eu und matrixrtc.example.eu, diese müsste Ihr natürlich überall wo Sie vorkommen ersetzen
    3. TLS Zertifikate für die beiden Domains

    Ordnerstruktur:

    Legt euch zuerst eine passende Ordnerstruktur an. Bei mir liegen die einzelnen Containerdefinitionen und Ihre Config Dateien in eigenen Ordnern unter /opt. Für meinen Matrix Server sieht das dann so aus:

    opt
    └── matrix
        ├── elementweb
        ├── livekit
        ├── postgres
        ├── synapse
        └── docker-compose.yaml

    Die docker-compose.yaml müsst ihr jetzt noch nicht erstellen.

    Homeserver.yaml generieren:

    Haben wir die Ordnerstruktur angelegt lassen wir uns von Synapse eine homeserver.yaml inkl. Keys, Secrets etc erstellen. Das macht Ihr mit folgendem Befehl, die homeserver.yaml findet Ihr danach im Ordner Synapse. Falls Ihr eine andere Ordnerstruktur habt müsst ihr das natürlich anpassen.

    docker run -it --rm \
      -v /opt/matrix/synapse:/data \
      -e SYNAPSE_SERVER_NAME=matrix.example.eu \
      -e SYNAPSE_REPORT_STATS=no \
      matrixdotorg/synapse:latest generate

    Homeserver.yaml bearbeiten:

    Jetzt schaut Ihr euch die homeserver.yaml an und führt die Änderungen durch die Ihr ein meinem Beispiel seht. Bitte nicht einfach Copy und Paste machen, dann sind eure Keys und Secrets weg. Schaut euch alle Zeilen an, wenn Ihr euch bei etwas nicht sicher seit dann schaut in die Synapse Doku. Wie gesagt, selber denken ist wichtig. Setzt auf jeden Fall ein sicheres Passwort für die Postgres Datenbank, Ihr werdet es auch in der Docker Compose Datei brauchen.

    # Configuration file for Synapse.
    #
    # This is a YAML file: see [1] for a quick introduction. Note in particular
    # that *indentation is important*: all the elements of a list or dictionary
    # should have the same indentation.
    #
    # [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
    #
    # For more information on how to configure Synapse, including a complete accounting of
    # each option, go to docs/usage/configuration/config_documentation.md or
    # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html
    server_name: "matrix.example.eu"
    pid_file: /data/homeserver.pid
    listeners:
      - port: 8008
        resources:
        - compress: false
          names:
          - client
          - federation
        tls: false
        type: http
        x_forwarded: true
    database:
      name: psycopg2
      args:
        user: synapse
        password: mySuperSecretPassword
        database: synapse
        host: db
        port: 5432
        cp_min: 5
        cp_max: 10
    log_config: "/data/matrix.example.eu.log.config"
    media_store_path: /data/media_store
    max_upload_size: 50M
    enable_registration: false
    enable_registration_without_verification: false
    registration_shared_secret: "AutoGenerated"
    # Retention policy
    retention:
      enabled: true
      default_policy:
        min_lifetime: 1d
        max_lifetime: 365d
    url_preview_enabled: true
    url_preview_ip_range_blacklist:
      - '127.0.0.0/8'
      - '10.0.0.0/8'
      - '172.16.0.0/12'
      - '192.168.0.0/16'
    report_stats: false
    macaroon_secret_key: "AutoGenerated"
    form_secret: "AutoGenerated"
    signing_key_path: "/data/matrix.example.eu.signing.key"
    trusted_key_servers:
      - server_name: "matrix.org"
    experimental_features:
      # MSC3266: Room summary API. Used for knocking over federation
      msc3266_enabled: true
      # MSC4222: needed for syncv2 state_after. This allows clients to
      # correctly track the state of the room.
      msc4222_enabled: true
      # MSC4140: Delayed events are required for proper call participation signalling. If disabled it is very likely that you end up with stuck calls in Matrix rooms
      msc4140_enabled: true
    
    # The maximum allowed duration by which sent events can be delayed, as
    # per MSC4140.
    max_event_delay_duration: 24h
    
    rc_message:
      # This needs to match at least e2ee key sharing frequency plus a bit of headroom
      # Note key sharing events are bursty
      per_second: 0.5
      burst_count: 30
      # This needs to match at least the heart-beat frequency plus a bit of headroom
      # Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
    rc_delayed_event_mgmt:
      per_second: 1
      burst_count: 20

    Docker Compose bearbeiten:

    Als nächstes nehmen wir uns die Docker Compose Datei vor. Auch darin ist eigentlich alles kommentiert was Ihr ändern müsst. Das wichtigeste ist das Datenbank Passwort sowie Key und Secret für Livekit. Wir Ihr diese generiert steht auch in den Kommentaren der Datei.

    services:
      synapse:
        image: matrixdotorg/synapse:latest
        container_name: synapse
        restart: unless-stopped
        volumes:
          - ./synapse:/data
        ports:
          - "127.0.0.1:8008:8008"   # Bind to loopback
        depends_on:
          - db
    
      db:
        image: postgres:16-alpine
        container_name: synapse-db
        restart: unless-stopped
        environment:
          POSTGRES_USER: synapse
          POSTGRES_PASSWORD: CHANGEME #also in synapse/homeserver.yaml
          POSTGRES_DB: synapse
          POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
        volumes:
          - ./postgres:/var/lib/postgresql/data
        ports:
          - "127.0.0.1:5432:5432"
    
      auth-service:
        image: ghcr.io/element-hq/lk-jwt-service:latest
        container_name: element-call-jwt
        hostname: auth-server
        environment:
          - LIVEKIT_JWT_PORT=8080
          - LIVEKIT_URL=https://matrixrtc.example.eu/livekit/sfu #CHANGEME
          - LIVEKIT_KEY=CHANGEME # use tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 64 to generate key / also change in livekit/config.yaml
          - LIVEKIT_SECRET=CHANGEME # use tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 64 to generate key / also change in livekit/config.yaml
          - LIVEKIT_FULL_ACCESS_HOMESERVERS=matrix.example.eu
        restart: unless-stopped
        ports:
          - 127.0.0.1:8070:8080 #Change 8070 to whichever port you want JWT to be available on locally
    
      livekit:
        image: livekit/livekit-server:latest
        container_name: element-call-livekit
        command: --config /etc/livekit.yaml
        ports:
          - 127.0.0.1:7880:7880/tcp
          - 7881:7881/tcp
          - 50100-50200:50100-50200/udp
        restart: unless-stopped
        volumes:
          - ./livekit/config.yaml:/etc/livekit.yaml:ro
    
      element-web:
        image: vectorim/element-web:latest
        restart: unless-stopped
        ports:
          - "127.0.0.1:8009:80"
        healthcheck:
          test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:80/version || exit 1"]
          start_period: "5s"
          interval: "15s"
          timeout: "5s"
        volumes:
          - ./element-web/config.json:/app/config.json
        depends_on:
          - synapse

    Livekit konfiguration:

    Nun ist die config.yaml im Unterordner livekit dran. Hier müsst Ihr eigentlich nur die externe IP eures Server sowie Key und Secret anpassen die Ihr gerade generiert habt. Übrigens wie ich letztens noch gelesen habe (https://sspaeth.de/2026/04/matrix-voip-and-livekit/) werdet ihr in den allermeisten Fällen keinen Turn Server brauchen. Also weder den in Livekit noch sowas wie CoTurn.

    port: 7880
    bind_addresses:
      - "0.0.0.0"
    rtc:
      tcp_port: 7881
      port_range_start: 50100
      port_range_end: 50200
      use_external_ip: true
      node_ip: Externe IP eures Servers
    room:
      auto_create: false
    logging:
      level: info
    turn:
      enabled: false
      domain: localhost
      cert_file: ""
      key_file: ""
      tls_port: 5349
      udp_port: 443
      external_tls: true
    keys:
      LIVEKIT_KEY: LIVEKIT_SECRET # Values from your docker compose, mind the space!

    Element Web konfiguration:

    Die letzte Config Datei, diesmal aber im json Format, die Ihr anpassen müsst ist die für Element Web, falls Ihr das verwenden wollt. Auch hier müsst Ihr vorallem die URL’s anpassen etc.

    {
        "default_server_config": {
            "m.homeserver": {
                "base_url": "https://matrix.example.eu",
                "server_name": "matrix.example.eu"
            },
            "m.identity_server": {
                "base_url": "https://vector.im"
            }
        },
        "disable_custom_urls": false,
        "disable_guests": false,
        "disable_login_language_selector": false,
        "disable_3pid_login": false,
        "force_verification": false,
        "brand": "Element",
        "default_widget_container_height": 280,
        "default_country_code": "DE",
        "show_labs_settings": false,
        "features": {
            "feature_video_rooms": true,
            "feature_group_calls": true,
            "feature_element_call_video_rooms": true,
            "feature_oidc_native_flow": true
        },
        "default_federate": true,
        "default_theme": "light",
        "room_directory": {
            "servers": ["https://matrix.example.eu"]
        },
        "setting_defaults": {
            "breadcrumbs": true
        },
        "element_call": {
            "url": "https://matrixrtc.example.eu"
        },
        "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
    }

    Nginx konfigurieren:

    Damit euer Synapse Server von aussen erreichbar ist, föderieren kann etc. müsst Ihr natürlich auch noch einen passenden reverse Proxy, in meinem Fall einen nginx einrichten. Dazu könnt Ihr folgende Config nehmen, natürlich müsst ihr die ganzen Domains sowie die Pfade zu den TLS Zertifikaten anspassen.

    # HTTPS redirect
    server {
        listen 80;
        listen [::]:80;
        server_name matrix.example.eu;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # Client API
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name matrix.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrix.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrix.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
    
        client_max_body_size 50M;
    
        # Well-known for Client Configuration
        location /.well-known/matrix/client {
            return 200 '{"m.homeserver": {"base_url": "https://matrix.example.eu"}, "m.identity_server": {"base_url": "https://vector.im"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://matrixrtc.example.eu/livekit/jwt"}]}';
            default_type application/json;
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, OPTIONS';
        }
    
        # Well-known for federation
        location /.well-known/matrix/server {
            return 200 '{"m.server":"matrix.example.eu:8448"}';
            default_type application/json;
        }
    
        location / {
            proxy_pass http://localhost:8009;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    
        # Forward to dockerized Synapse
        location ~* ^(\/_matrix|\/_synapse\/client) {
            proxy_pass         http://localhost:8008;
            proxy_set_header   X-Forwarded-For $remote_addr;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
    
            proxy_read_timeout    600;
            proxy_connect_timeout 600;
            proxy_send_timeout    600;
        }
    }
    
    # Federation Port 8448
    server {
        listen 8448 ssl http2;
        listen [::]:8448 ssl http2;
        server_name matrix.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrix.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrix.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
        client_max_body_size 50M;
    
    
        location / {
            proxy_pass         http://localhost:8008;
            proxy_set_header   X-Forwarded-For $remote_addr;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
        }
    }
    # HTTPS redirect
    server {
        listen 80;
        listen [::]:80;
        server_name matrixrtc.example.eu;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # HTTPS Client API
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name matrixrtc.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrixrtc.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrixrtc.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
    location ^~ /livekit/jwt/ {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    
          # MatrixRTC Authorization Service running at port 8080
          proxy_pass http://localhost:8070/;
        }
    
        location ^~ /livekit/sfu/ {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    
          proxy_send_timeout 120;
          proxy_read_timeout 120;
          proxy_buffering off;
    
          proxy_set_header Accept-Encoding gzip;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
    
    
          # LiveKit SFU websocket connection running at port 7880
          proxy_pass http://localhost:7880/;
        }
    }
    
    

    Jetzt noch die Config mittels symlink eurem nginx bekant machen und diesen reloaden.

    Synapse Server starten:

    Danach konnt Ihr wieder in den Ordner /opt/matrix wechseln und den Synapse Server starten:

    docker compose up

    Ich habe hier das detachen erst einmal weg gelassen, so könnt Ihr die Ausgaben beobachten und wisst auch wann die Datenbankinitialisierung vorbei ist.

    Benutzer anlegen:

    Nun müsst Ihr natürlich noch User anlegen, da wir die Registrierung deaktiviert haben, machen wir das über die Kommandozeile. Den ersten User machen wir auch gleich zum Admin, bei den anderen Usern tauscht ihr das –admin gegen ein –no-admin.

    docker exec -it synapse register_new_matrix_user \
      http://localhost:8008 \
      -c /data/homeserver.yaml \
      -u meinErsterUser \
      -p SuperSicheresPasswort \
      --admin

    Nun sollte euer eigener Synapse Server laufen und auch mit anderen Server föderieren können. Falls Ihr konstruktive Anmerkungen habt, eine Fehler in der Config seht etc. dann schreibt einfach einen Kommentar. Wie gesagt das ganze aufzusetzen ist extrem komplex und den einen ultimativen Guide gibt es nicht (und der hier ist es sicher auch nicht).

    Aber ich hoffe ich kann auf die Weise den einen oder anderen dazu bewegen sich auch so ein System aufzusetzen und damit dazu beizutragen das Matrix Ökosystem ein bisschen resilienter zu machen.

    #element #linux #matrix #opensource #selfhosting #synapse #unplugbigtech #unplugtrump @bjoern
  4. Eigenen Synapse Server für das Matrix Protokoll betreiben inklusive Element Call

    blog.sengotta.net/eigenen-syna

    Mal wieder ein Beitrag der vor allem mir als Gedankenstütze dienen soll. Und zwar geht es diesmal um Synapse, dem Referenzserver für das Matrix Protokoll.

    Wer hier gelandet ist wird sicher schon wissen was Synapse bzw. das Matrix Protokoll ist. Über diesen Server kann man vor allem chatten aber auch Video- und Audioanrufe abwickeln und noch vieles mehr. Das Matrix Protokoll ist extrem mächtig. Das ist nicht immer ein Vorteil, denn es zu implementieren ist somit auch extrem schwer. Das führt auch dazu das es bisher eigentlich kaum eine ernst zunehmende Alternative zu Synapse oder den Element Clients gibt wenn man den vollen Funktionsumfang nutzen möchte.

    Aber warum mach ich mir die Arbeit. Naja im Alltag nutze ich überwiegend Signal, was meiner Meinung nach ein super Dienst ist, auch wenn hier manche Leute jetzt wieder Schnappatmung kriegen. Aber dieser Dienst ist halt zentralisiert, an eine Mobilfunknummer gebunden, liegt im Machtbereich von Donald Trump und falls die Chatkontrolle kommt dann hat man auch schon angedroht sich aus dem europäischen Markt zurück zu ziehen.

    Mein eigener Synapse Server ist also mein Plan B in Sachen Kommunikation, ausserdem ist so eine Chatplattform auch ganz praktisch in Bezug auf Smarthome Benachrichtigungen, Datenschutz und Co. Des Weiteren ist Matrix als dezentrales System gedacht, von daher ist es geradezu traurig bis gefährlich wie viele User dieses Ökosystems Ihr Zuhause auf der Hauptinstanz matrix.org haben.

    Leider ist das Setup eines Synapse Servers inkl. dem Backend für Element Call nicht trivial, deswegen habe ich das hier mal zusammengefasst. Aber nein das hier ist jetzt keine Anleitung wo ich jedes Fitzelchen kommentiere etc. Teilweise muss man auch das eigene Hirn noch einschalten. Ausserdem ist das ganze an mein spezifisches Setup (Docker mit nativ installiertem nginx als reverse Proxy) angepasst. So oder so ist es ggf. eine Inspiration für euer eigenes Setup. Auch ich musste mir die Infos an etlichen Stellen zusammensuchen. Ich werde hier die einzelnen Config Dateien in den Beitrag einbetten so das Ihr nachschauen könnt was Ihr ändern müsst.

    Eigentlich wollte ich Sie auf Codeberg laden aber der Dienst kämpft wohl gerade mit Problemen.

    Am Ende solltet Ihr einen Synapse Server inkl. Element Web und Element Call am laufen haben.

    Vorraussetzungen:

    1. ein aus dem Internet erreichbarer Linux Server mit Docker, Docker compose und nginx. Falls Ihr eine Firewall einsetzt denkt daran diese entsprechend einzurichten und die notwendigen Ports freizugeben
    2. Zwei Domains, ich nutze im Beispiel matrix.example.eu und matrixrtc.example.eu, diese müsste Ihr natürlich überall wo Sie vorkommen ersetzen
    3. TLS Zertifikate für die beiden Domains

    Ordnerstruktur:

    Legt euch zuerst eine passende Ordnerstruktur an. Bei mir liegen die einzelnen Containerdefinitionen und Ihre Config Dateien in eigenen Ordnern unter /opt. Für meinen Matrix Server sieht das dann so aus:

    opt
    └── matrix
        ├── elementweb
        ├── livekit
        ├── postgres
        ├── synapse
        └── docker-compose.yaml

    Die docker-compose.yaml müsst ihr jetzt noch nicht erstellen.

    Homeserver.yaml generieren:

    Haben wir die Ordnerstruktur angelegt lassen wir uns von Synapse eine homeserver.yaml inkl. Keys, Secrets etc erstellen. Das macht Ihr mit folgendem Befehl, die homeserver.yaml findet Ihr danach im Ordner Synapse. Falls Ihr eine andere Ordnerstruktur habt müsst ihr das natürlich anpassen.

    docker run -it --rm \
      -v /opt/matrix/synapse:/data \
      -e SYNAPSE_SERVER_NAME=matrix.example.eu \
      -e SYNAPSE_REPORT_STATS=no \
      matrixdotorg/synapse:latest generate

    Homeserver.yaml bearbeiten:

    Jetzt schaut Ihr euch die homeserver.yaml an und führt die Änderungen durch die Ihr ein meinem Beispiel seht. Bitte nicht einfach Copy und Paste machen, dann sind eure Keys und Secrets weg. Schaut euch alle Zeilen an, wenn Ihr euch bei etwas nicht sicher seit dann schaut in die Synapse Doku. Wie gesagt, selber denken ist wichtig. Setzt auf jeden Fall ein sicheres Passwort für die Postgres Datenbank, Ihr werdet es auch in der Docker Compose Datei brauchen.

    # Configuration file for Synapse.
    #
    # This is a YAML file: see [1] for a quick introduction. Note in particular
    # that *indentation is important*: all the elements of a list or dictionary
    # should have the same indentation.
    #
    # [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
    #
    # For more information on how to configure Synapse, including a complete accounting of
    # each option, go to docs/usage/configuration/config_documentation.md or
    # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html
    server_name: "matrix.example.eu"
    pid_file: /data/homeserver.pid
    listeners:
      - port: 8008
        resources:
        - compress: false
          names:
          - client
          - federation
        tls: false
        type: http
        x_forwarded: true
    database:
      name: psycopg2
      args:
        user: synapse
        password: mySuperSecretPassword
        database: synapse
        host: db
        port: 5432
        cp_min: 5
        cp_max: 10
    log_config: "/data/matrix.example.eu.log.config"
    media_store_path: /data/media_store
    max_upload_size: 50M
    enable_registration: false
    enable_registration_without_verification: false
    registration_shared_secret: "AutoGenerated"
    # Retention policy
    retention:
      enabled: true
      default_policy:
        min_lifetime: 1d
        max_lifetime: 365d
    url_preview_enabled: true
    url_preview_ip_range_blacklist:
      - '127.0.0.0/8'
      - '10.0.0.0/8'
      - '172.16.0.0/12'
      - '192.168.0.0/16'
    report_stats: false
    macaroon_secret_key: "AutoGenerated"
    form_secret: "AutoGenerated"
    signing_key_path: "/data/matrix.example.eu.signing.key"
    trusted_key_servers:
      - server_name: "matrix.org"
    experimental_features:
      # MSC3266: Room summary API. Used for knocking over federation
      msc3266_enabled: true
      # MSC4222: needed for syncv2 state_after. This allows clients to
      # correctly track the state of the room.
      msc4222_enabled: true
      # MSC4140: Delayed events are required for proper call participation signalling. If disabled it is very likely that you end up with stuck calls in Matrix rooms
      msc4140_enabled: true
    
    # The maximum allowed duration by which sent events can be delayed, as
    # per MSC4140.
    max_event_delay_duration: 24h
    
    rc_message:
      # This needs to match at least e2ee key sharing frequency plus a bit of headroom
      # Note key sharing events are bursty
      per_second: 0.5
      burst_count: 30
      # This needs to match at least the heart-beat frequency plus a bit of headroom
      # Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s
    rc_delayed_event_mgmt:
      per_second: 1
      burst_count: 20

    Docker Compose bearbeiten:

    Als nächstes nehmen wir uns die Docker Compose Datei vor. Auch darin ist eigentlich alles kommentiert was Ihr ändern müsst. Das wichtigeste ist das Datenbank Passwort sowie Key und Secret für Livekit. Wir Ihr diese generiert steht auch in den Kommentaren der Datei.

    services:
      synapse:
        image: matrixdotorg/synapse:latest
        container_name: synapse
        restart: unless-stopped
        volumes:
          - ./synapse:/data
        ports:
          - "127.0.0.1:8008:8008"   # Bind to loopback
        depends_on:
          - db
    
      db:
        image: postgres:16-alpine
        container_name: synapse-db
        restart: unless-stopped
        environment:
          POSTGRES_USER: synapse
          POSTGRES_PASSWORD: CHANGEME #also in synapse/homeserver.yaml
          POSTGRES_DB: synapse
          POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
        volumes:
          - ./postgres:/var/lib/postgresql/data
        ports:
          - "127.0.0.1:5432:5432"
    
      auth-service:
        image: ghcr.io/element-hq/lk-jwt-service:latest
        container_name: element-call-jwt
        hostname: auth-server
        environment:
          - LIVEKIT_JWT_PORT=8080
          - LIVEKIT_URL=https://matrixrtc.example.eu/livekit/sfu #CHANGEME
          - LIVEKIT_KEY=CHANGEME # use tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 64 to generate key / also change in livekit/config.yaml
          - LIVEKIT_SECRET=CHANGEME # use tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 64 to generate key / also change in livekit/config.yaml
          - LIVEKIT_FULL_ACCESS_HOMESERVERS=matrix.example.eu
        restart: unless-stopped
        ports:
          - 127.0.0.1:8070:8080 #Change 8070 to whichever port you want JWT to be available on locally
    
      livekit:
        image: livekit/livekit-server:latest
        container_name: element-call-livekit
        command: --config /etc/livekit.yaml
        ports:
          - 127.0.0.1:7880:7880/tcp
          - 7881:7881/tcp
          - 50100-50200:50100-50200/udp
        restart: unless-stopped
        volumes:
          - ./livekit/config.yaml:/etc/livekit.yaml:ro
    
      element-web:
        image: vectorim/element-web:latest
        restart: unless-stopped
        ports:
          - "127.0.0.1:8009:80"
        healthcheck:
          test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:80/version || exit 1"]
          start_period: "5s"
          interval: "15s"
          timeout: "5s"
        volumes:
          - ./element-web/config.json:/app/config.json
        depends_on:
          - synapse

    Livekit konfiguration:

    Nun ist die config.yaml im Unterordner livekit dran. Hier müsst Ihr eigentlich nur die externe IP eures Server sowie Key und Secret anpassen die Ihr gerade generiert habt. Übrigens wie ich letztens noch gelesen habe (https://sspaeth.de/2026/04/matrix-voip-and-livekit/) werdet ihr in den allermeisten Fällen keinen Turn Server brauchen. Also weder den in Livekit noch sowas wie CoTurn.

    port: 7880
    bind_addresses:
      - "0.0.0.0"
    rtc:
      tcp_port: 7881
      port_range_start: 50100
      port_range_end: 50200
      use_external_ip: true
      node_ip: Externe IP eures Servers
    room:
      auto_create: false
    logging:
      level: info
    turn:
      enabled: false
      domain: localhost
      cert_file: ""
      key_file: ""
      tls_port: 5349
      udp_port: 443
      external_tls: true
    keys:
      LIVEKIT_KEY: LIVEKIT_SECRET # Values from your docker compose, mind the space!

    Element Web konfiguration:

    Die letzte Config Datei, diesmal aber im json Format, die Ihr anpassen müsst ist die für Element Web, falls Ihr das verwenden wollt. Auch hier müsst Ihr vorallem die URL’s anpassen etc.

    {
        "default_server_config": {
            "m.homeserver": {
                "base_url": "https://matrix.example.eu",
                "server_name": "matrix.example.eu"
            },
            "m.identity_server": {
                "base_url": "https://vector.im"
            }
        },
        "disable_custom_urls": false,
        "disable_guests": false,
        "disable_login_language_selector": false,
        "disable_3pid_login": false,
        "force_verification": false,
        "brand": "Element",
        "default_widget_container_height": 280,
        "default_country_code": "DE",
        "show_labs_settings": false,
        "features": {
            "feature_video_rooms": true,
            "feature_group_calls": true,
            "feature_element_call_video_rooms": true,
            "feature_oidc_native_flow": true
        },
        "default_federate": true,
        "default_theme": "light",
        "room_directory": {
            "servers": ["https://matrix.example.eu"]
        },
        "setting_defaults": {
            "breadcrumbs": true
        },
        "element_call": {
            "url": "https://matrixrtc.example.eu"
        },
        "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
    }

    Nginx konfigurieren:

    Damit euer Synapse Server von aussen erreichbar ist, föderieren kann etc. müsst Ihr natürlich auch noch einen passenden reverse Proxy, in meinem Fall einen nginx einrichten. Dazu könnt Ihr folgende Config nehmen, natürlich müsst ihr die ganzen Domains sowie die Pfade zu den TLS Zertifikaten anspassen.

    # HTTPS redirect
    server {
        listen 80;
        listen [::]:80;
        server_name matrix.example.eu;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # Client API
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name matrix.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrix.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrix.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
    
        client_max_body_size 50M;
    
        # Well-known for Client Configuration
        location /.well-known/matrix/client {
            return 200 '{"m.homeserver": {"base_url": "https://matrix.example.eu"}, "m.identity_server": {"base_url": "https://vector.im"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://matrixrtc.example.eu/livekit/jwt"}]}';
            default_type application/json;
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, OPTIONS';
        }
    
        # Well-known for federation
        location /.well-known/matrix/server {
            return 200 '{"m.server":"matrix.example.eu:8448"}';
            default_type application/json;
        }
    
        location / {
            proxy_pass http://localhost:8009;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    
        # Forward to dockerized Synapse
        location ~* ^(\/_matrix|\/_synapse\/client) {
            proxy_pass         http://localhost:8008;
            proxy_set_header   X-Forwarded-For $remote_addr;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
    
            proxy_read_timeout    600;
            proxy_connect_timeout 600;
            proxy_send_timeout    600;
        }
    }
    
    # Federation Port 8448
    server {
        listen 8448 ssl http2;
        listen [::]:8448 ssl http2;
        server_name matrix.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrix.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrix.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
        client_max_body_size 50M;
    
    
        location / {
            proxy_pass         http://localhost:8008;
            proxy_set_header   X-Forwarded-For $remote_addr;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
        }
    }
    # HTTPS redirect
    server {
        listen 80;
        listen [::]:80;
        server_name matrixrtc.example.eu;
    
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    # HTTPS Client API
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name matrixrtc.example.eu;
    
        ssl_certificate     /etc/letsencrypt/live/matrixrtc.example.eu/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/matrixrtc.example.eu/privkey.pem;
        ssl_protocols       TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    
    location ^~ /livekit/jwt/ {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    
          # MatrixRTC Authorization Service running at port 8080
          proxy_pass http://localhost:8070/;
        }
    
        location ^~ /livekit/sfu/ {
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
    
          proxy_send_timeout 120;
          proxy_read_timeout 120;
          proxy_buffering off;
    
          proxy_set_header Accept-Encoding gzip;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
    
    
          # LiveKit SFU websocket connection running at port 7880
          proxy_pass http://localhost:7880/;
        }
    }
    
    

    Jetzt noch die Config mittels symlink eurem nginx bekant machen und diesen reloaden.

    Synapse Server starten:

    Danach konnt Ihr wieder in den Ordner /opt/matrix wechseln und den Synapse Server starten:

    docker compose up

    Ich habe hier das detachen erst einmal weg gelassen, so könnt Ihr die Ausgaben beobachten und wisst auch wann die Datenbankinitialisierung vorbei ist.

    Benutzer anlegen:

    Nun müsst Ihr natürlich noch User anlegen, da wir die Registrierung deaktiviert haben, machen wir das über die Kommandozeile. Den ersten User machen wir auch gleich zum Admin, bei den anderen Usern tauscht ihr das –admin gegen ein –no-admin.

    docker exec -it synapse register_new_matrix_user \
      http://localhost:8008 \
      -c /data/homeserver.yaml \
      -u meinErsterUser \
      -p SuperSicheresPasswort \
      --admin

    Nun sollte euer eigener Synapse Server laufen und auch mit anderen Server föderieren können. Falls Ihr konstruktive Anmerkungen habt, eine Fehler in der Config seht etc. dann schreibt einfach einen Kommentar. Wie gesagt das ganze aufzusetzen ist extrem komplex und den einen ultimativen Guide gibt es nicht (und der hier ist es sicher auch nicht).

    Aber ich hoffe ich kann auf die Weise den einen oder anderen dazu bewegen sich auch so ein System aufzusetzen und damit dazu beizutragen das Matrix Ökosystem ein bisschen resilienter zu machen.

    #element #linux #matrix #opensource #selfhosting #synapse #unplugbigtech #unplugtrump @bjoern
  5. So i moved my own Synapse Server to its final TLD. Time to start using it regulary, till now i have only playing around with it, trying to get Element Call etc. working properly.
    #selfhosting #matrix #synapse #unplugbigtech #unplugtrump

  6. So i moved my own Synapse Server to its final TLD. Time to start using it regulary, till now i have only playing around with it, trying to get Element Call etc. working properly.
    #selfhosting #matrix #synapse #unplugbigtech #unplugtrump

  7. Produktiv-Updates vom Handy aus steuern — mit einem AI-Agenten im Matrix-Chat 🤖📱

    Samstagmorgen, Kaffee in Reichweite, und mein selbstgehosteter Stack meldet drei verfügbare Updates. Also kurzerhand per Element X auf dem Handy dem AI-Agenten (Hermes, selbstgehostet) geschrieben: „Mach mal."

    Was dann passierte — komplett per Chat, ohne SSH, ohne Laptop:

    Forgejo (Git-Server): Patch-Update eingespielt, Healthchecks verifiziert, Changelog-Eintrag committed und gepusht.

    Synapse (Matrix-Homeserver): Minor-Update inkl. automatischer DB-Schema-Migration. Release Notes wurden vorher auf Breaking Changes gescannt — betraf uns nicht, grünes Licht. Das Update lief übrigens über denselben Homeserver, der gerade neu gestartet wurde. Die Chat-Verbindung hat's überlebt. Selbstheilend quasi 😄

    Element Web (Web-Client): Patch-Update, Config-Mount geprüft, alles da.

    Nebenbei wurde der Update-Prozess selbst besser: Alle drei Dienste von floating latest-Tags auf Version-Pinning umgestellt, also reproduzierbar und rollback-fähig. Für jeden Dienst wurde ein wiederverwendbares Update-Playbook angelegt, inklusive der Fallstricke, die man nur einmal erleben will. Und ein fehlender Changelog-Eintrag vom letzten Major-Upgrade wurde nachträglich recherchiert und dokumentiert.

    Der eigentliche Mindbender: Ich habe Production-Updates von einem Handy-Chat aus angestoßen — und der Agent hat nicht einfach Befehle abgearbeitet, sondern Versionen geprüft, Release Notes gelesen, verifiziert, dokumentiert und sein eigenes Wissen für das nächste Mal erweitert.

    Selfhosting + AI-Agenten + offene Protokolle ist eine ziemlich starke Kombination.

    #selfhosting #matrix #forgejo #synapse #ai #homelab #automation #vibeops #kimik3 #hermes_agent

  8. Produktiv-Updates vom Handy aus steuern — mit einem AI-Agenten im Matrix-Chat 🤖📱

    Samstagmorgen, Kaffee in Reichweite, und mein selbstgehosteter Stack meldet drei verfügbare Updates. Also kurzerhand per Element X auf dem Handy dem AI-Agenten (Hermes, selbstgehostet) geschrieben: „Mach mal."

    Was dann passierte — komplett per Chat, ohne SSH, ohne Laptop:

    Forgejo (Git-Server): Patch-Update eingespielt, Healthchecks verifiziert, Changelog-Eintrag committed und gepusht.

    Synapse (Matrix-Homeserver): Minor-Update inkl. automatischer DB-Schema-Migration. Release Notes wurden vorher auf Breaking Changes gescannt — betraf uns nicht, grünes Licht. Das Update lief übrigens über denselben Homeserver, der gerade neu gestartet wurde. Die Chat-Verbindung hat's überlebt. Selbstheilend quasi 😄

    Element Web (Web-Client): Patch-Update, Config-Mount geprüft, alles da.

    Nebenbei wurde der Update-Prozess selbst besser: Alle drei Dienste von floating latest-Tags auf Version-Pinning umgestellt, also reproduzierbar und rollback-fähig. Für jeden Dienst wurde ein wiederverwendbares Update-Playbook angelegt, inklusive der Fallstricke, die man nur einmal erleben will. Und ein fehlender Changelog-Eintrag vom letzten Major-Upgrade wurde nachträglich recherchiert und dokumentiert.

    Der eigentliche Mindbender: Ich habe Production-Updates von einem Handy-Chat aus angestoßen — und der Agent hat nicht einfach Befehle abgearbeitet, sondern Versionen geprüft, Release Notes gelesen, verifiziert, dokumentiert und sein eigenes Wissen für das nächste Mal erweitert.

    Selfhosting + AI-Agenten + offene Protokolle ist eine ziemlich starke Kombination.

  9. Back in December last year, I suffered a massive incident on the home infra, which lead to all of the media’s of the Synapse server (decentralised one-place messaging service) to be lost

    Well, surprise surprise, the other day I found that my backup routine had done what it was supposed to

    Hourly cumulative backups, daily full backups, weekly backups retention for 3 months, and monthly backups retention for 1 year

    So I restored the latest before-outage backup, diffed both the production and restored volume, and transferred over the difference

    The immense sensation of relief realising everything worked as expected, and that all the memories with the SO are still there

    One more tale on how important backups are !

    #k8s #kubernetes #k3s #homelab #selfhosted #datarecovery #selfhosting #server #backups #longhorn #matrix #synapse

  10. Back in December last year, I suffered a massive incident on the home infra, which lead to all of the media’s of the Synapse server (decentralised one-place messaging service) to be lost

    Well, surprise surprise, the other day I found that my backup routine had done what it was supposed to

    Hourly cumulative backups, daily full backups, weekly backups retention for 3 months, and monthly backups retention for 1 year

    So I restored the latest before-outage backup, diffed both the production and restored volume, and transferred over the difference

    The immense sensation of relief realising everything worked as expected, and that all the memories with the SO are still there

    One more tale on how important backups are !

    #k8s #kubernetes #k3s #homelab #selfhosted #datarecovery #selfhosting #server #backups #longhorn #matrix #synapse

  11. ich hab bisher alle mit telegram angesprochen

    1. problem
    web app telegram zeigt manchmal kein nachrichten an:
    This message is currently not supported on Telegram Web. Try getdesktop.telegram.org
    -> mobbing das ich die app installieren soll 🖕

    2. problem:
    app hängt immer ma wieder in android - vllt zu große chats? trotzdem kacke

    3. problem:
    datenschutz - warum sollen die daten über diesen dubiosen kanal laufen

    4. problem:
    die chatbots können nicht einfach miteinander reden

    Lösung:
    auf meinem vServer

    Kurz und knapp =)

    Telegram wird langsam unbequem — App läuft schlechter, Datenschutz ist mir wichtiger geworden. Also: weg von fremden Plattformen, hin zu self-hosted. Setze Matrix (Synapse) auf eigenem VServer auf, wechsle auf Element als Client. Künftig schreibe ich direkt mit meinen KI-Agenten — und die Agenten stimmen sich untereinander in geteilten Räumen ab. Volle Kontrolle über meine Daten, E2E-Verschlüsselung, eigene Infrastruktur. Less cloud, more sovereignty. 🖥️"

  12. @parleur
    C'est le protocole qui est lourd et pénible ou c'est seulement #synapse ? 😝

    Tu peux essayer #continuwuity, il parait que c'est bien plus léger.

    Ou encore, tu peux essayer #XMPP.

  13. Watch until the end to hear about how George Santos, Mr. Beast, Eric Trump & billionaires Peter Thiel & Marc Andreesen are involved...
    ... oh, and also what's happened so far to the CEO of the most active bank involved with this "Neobank" scam. (Hint: He was arrested for child pornography)
    #neobanks #evolvebank #synapse

  14. Watch until the end to hear about how George Santos, Mr. Beast, Eric Trump & billionaires Peter Thiel & Marc Andreesen are involved...
    ... oh, and also what's happened so far to the CEO of the most active bank involved with this "Neobank" scam. (Hint: He was arrested for child pornography)
    #neobanks #evolvebank #synapse

  15. How customers got ripped off when they thought they were putting their money in a safe, FDIC insured bank.
    #Fintech #Synapse #Banking #FDIC #Evolve #Yotta #AdamMoelis
    📺
    youtu.be/hiE7NvONU5U?is=nleKpF

  16. How customers got ripped off when they thought they were putting their money in a safe, FDIC insured bank.
    #Fintech #Synapse #Banking #FDIC #Evolve #Yotta #AdamMoelis
    📺
    youtu.be/hiE7NvONU5U?is=nleKpF

  17. Установка и настройка matrix (Synapse), MAS, LiveKit, lk‑jwt‑service, Element‑web, Ketesa совместно с панелью 3x‑ui

    Возникла идея написать подробную инструкцию по установке и настройке matrix. Всё, что нашел в интернете — либо устаревшая, неактуальная информация 3–4 летней давности без использования MAS, либо неполная информация с обрезанными конфигурационными файлами, по типу «догадайся сам и допиши». Также все инструкции, которые есть в интернете, в основном по установке в контейнере docker. Я же поделюсь с вами инструкцией по установке без каких либо контейнеров. В условиях блокировки Телеграм и других популярных мессенджеров, протокол matrix дает возможность организовать, например, связь между членами семьи, родственниками и друзьями, не используя ВПН. Постараюсь доступно объяснить и показать все шаги установки и настройки, чтобы это было понятно большинству «чайников». Под «чайниками» я подразумеваю людей, которые знают, что такое терминал в линукс, и на базовом уровне умеют им пользоваться. Зачем нужна установка matrix совместно с панелью 3x‑ui? Всё просто — для экономии денег. Если у вас уже есть сервер с установленной панелью, то зачем арендовать еще один сервер для matrix? Всё можно установить на один сервер. Другой вопрос — правильно ли это? Возможно нет, но у меня такая схема работает несколько месяцев без сбоев.

    habr.com/ru/articles/1057762/

    #matrix #synapse #MAS #Elementweb #livekit #установка #настройка #3xui #Ketesa #lkjwtservice

  18. #matrix #synapse #element

    If anyone instantly knows what is misconfigured, Synapse and/or Matrix is pinging the wrong URL for matrix; it's matrix.zelda.zone not just zelda.zone.

    I even followed a tutorial step-by-step and this is about the 4th issue I have had so far, still have not successfully made a chat or posted a message.

  19. #matrix #synapse #element

    If anyone instantly knows what is misconfigured, Synapse and/or Matrix is pinging the wrong URL for matrix; it's matrix.zelda.zone not just zelda.zone.

    I even followed a tutorial step-by-step and this is about the 4th issue I have had so far, still have not successfully made a chat or posted a message.

  20. Как мы строили безопасную микросервисную архитектуру с Service Mesh: интеграция с базами данных и масштабированиe

    Привет, Habr! Меня зовут Валентин, я DevOps-инженер команды Platform V Kintsugi. Мы занимаемся развитием облачного сервиса и на практике регулярно сталкиваемся как с архитектурными задачами построения распределённых систем, так и с вопросами обеспечения их безопасности. В предыдущей части мы подробно разобрали механизм делегирования TLS-соединения на уровень Service Mesh и показали, как Egress Gateway может выступать полноценным участником PostgreSQL handshake. Однако этот сценарий рассматривался в упрощённой конфигурации — один сервис, один сертификат, одно подключение.

    habr.com/ru/companies/sberbank

    #микросервисная_архитектура #kintsugi #synapse #сбертех #istio #service_mesh #pangolin

  21. Do you know about Ketesa (formerly Synapse Admin)? It just got a website: ketesa.app

    #matrix #synapse #synapse-admin #ketesa

  22. Do you know about Ketesa (formerly Synapse Admin)? It just got a website: ketesa.app

    #matrix #synapse #synapse-admin #ketesa

  23. Keinen Bock mehr auf #whatsapp
    Ich habe für Familie und Freund meinen eigenen #matrix #synapse #chat #server installiert.
    Einige sind schon gejoined.
    Es gibt natürlich immer so Harcore faule die keine Veränderungen wollen, aber die müssen dann künftig auf mich verzichten.

  24. Command-line admin tool for Matrix/Synapse homeservers written for PHP 8.4+. Wraps the Synapse Admin API for day-to-day user, room, media, and federation management.

    codeberg.org/joho1968/mtxctl

    #synapse #matrix #devops #php #opensource #foss #oss #dataskydd #dataprotection #gdpr #privacy

  25. Command-line admin tool for Matrix/Synapse homeservers written for PHP 8.4+. Wraps the Synapse Admin API for day-to-day user, room, media, and federation management.

    codeberg.org/joho1968/mtxctl

    #synapse #matrix #devops #php #opensource #foss #oss #dataskydd #dataprotection #gdpr #privacy

  26. Reusable PHP 8.4+ library for interacting with a Matrix/Synapse homeserver.

    Provides an Application Service client (MatrixClient) and a Synapse Admin API client (SynapseAdminClient. No framework dependencies.

    codeberg.org/joho1968/matrix-p

    #synapse #homeserver #php #php8 #matrix #opensource #foss #oss #devops #programming #programmer

  27. Reusable PHP 8.4+ library for interacting with a Matrix/Synapse homeserver.

    Provides an Application Service client (MatrixClient) and a Synapse Admin API client (SynapseAdminClient. No framework dependencies.

    codeberg.org/joho1968/matrix-p

    #synapse #homeserver #php #php8 #matrix #opensource #foss #oss #devops #programming #programmer

  28. I couldn't quite get the various Mattermost ➡️ Matrix/Synapse migration tools working.

    So after successfully "banzai testing" ITM with our own Mattermost with posts dating back to 2019 and 800+ MB of attachments, I'll be releasing it as AGPLv3 shortly.

    It's a PHP 8.4+ application (you only need CLI, stop moaning 😎).

    ITM? Aye, "IntoTheMatrix", ButOfCourse!

    #matrix #synapse #mattermost #chat #migration #devops #php #opensource #foss #oss #datamigration #programming #developer #development

  29. I couldn't quite get the various Mattermost ➡️ Matrix/Synapse migration tools working.

    So after successfully "banzai testing" ITM with our own Mattermost with posts dating back to 2019 and 800+ MB of attachments, I'll be releasing it as AGPLv3 shortly.

    It's a PHP 8.4+ application (you only need CLI, stop moaning 😎).

    ITM? Aye, "IntoTheMatrix", ButOfCourse!

    #matrix #synapse #mattermost #chat #migration #devops #php #opensource #foss #oss #datamigration #programming #developer #development

  30. Как мы строили безопасную микросервисную архитектуру с Service Mesh: интеграция с базами данных

    Привет, Хабр! Меня зовут Валентин, я DevOps-инженер команды Platform V Kintsugi . Мы развиваем облачный сервис и регулярно сталкиваемся как с архитектурными задачами построения распределённых систем, так и с вопросами обеспечения их безопасности. Наш продукт — консоль управления базами данных, поэтому значительная часть его архитектуры построена вокруг взаимодействия микросервисов с СУБД. Именно этот контур лежит в основе большинства операций — от управления и администрирования до мониторинга и обслуживания, — а значит, требования к его надёжности и безопасности становятся критически важными. В этом контексте особенно интересен вопрос организации взаимодействия сервисов с внешними базами данных. В статье мы сосредоточимся на этом прикладном аспекте и рассмотрим его на примере PostgreSQL.

    habr.com/ru/companies/sberbank

    #микросервисная_архитектура #kintsugi #synapse #сбертех #istio #service_mesh

  31. ✨ Tuto : Configuration CORS Nginx pour Synapse Admin
    Un guide rapide pour ne plus jamais voir d'erreur de connexion. Bonne lecture !
    👉 wiki.blablalinux.be/fr/synapse
    #Synapse #Matrix #Nginx #Tips #BlablaLinux

  32. ✨ Tuto : Configuration CORS Nginx pour Synapse Admin
    Un guide rapide pour ne plus jamais voir d'erreur de connexion. Bonne lecture !
    👉 wiki.blablalinux.be/fr/synapse
    #Synapse #Matrix #Nginx #Tips #BlablaLinux

  33. 🚀 Synapse Admin est maintenant public !
    J'ai une bonne nouvelle : mon instance de #Synapse Admin est désormais accessible à tous. Si vous gérez un serveur #Matrix Synapse, vous pouvez maintenant utiliser cet outil pour faciliter votre administration au quotidien.

    Accès au service : synapse-admin.blablalinux.be

    Besoin d'aide ? Consultez la documentation officielle : etke.cc/help/extras/ketesa/

    Profitez bien de cet outil pour gérer vos serveurs !

  34. 🚀 Synapse Admin est maintenant public !
    J'ai une bonne nouvelle : mon instance de #Synapse Admin est désormais accessible à tous. Si vous gérez un serveur #Matrix Synapse, vous pouvez maintenant utiliser cet outil pour faciliter votre administration au quotidien.

    Accès au service : synapse-admin.blablalinux.be

    Besoin d'aide ? Consultez la documentation officielle : etke.cc/help/extras/ketesa/

    Profitez bien de cet outil pour gérer vos serveurs !

  35. [YunoHost]

    Who has Experience with using YunoHost for managing Services like Mastodon or Pixelfed or Matrix/Synapse or else in a kinda starter VPS(2cores/4gb Ram) at a Hoster like Hetzner.de or OVH or Bunny.net or DigitalOcean or similar?

    How long have you doing it?

    What were the Pitfalls/Problems you encounter?

    How stable does it run with a certain amount of Services on?

    Thank you for your Participation and maybe sharing this Post around with a Boost for better visibility in the Fediverse.

    #YunoHost #Hosting #Hoster #DIY #Fediverse #Mastodon #Matrix #Synapse #Pixelfed #Help #Experience #VPS #Hetzner_de #OVH #DigitalOcean #Bunny_net #Services

  36. [YunoHost]

    Who has Experience with using YunoHost for managing Services like Mastodon or Pixelfed or Matrix/Synapse or else in a kinda starter VPS(2cores/4gb Ram) at a Hoster like Hetzner.de or OVH or Bunny.net or DigitalOcean or similar?

    How long have you doing it?

    What were the Pitfalls/Problems you encounter?

    How stable does it run with a certain amount of Services on?

    Thank you for your Participation and maybe sharing this Post around with a Boost for better visibility in the Fediverse.

    #YunoHost #Hosting #Hoster #DIY #Fediverse #Mastodon #Matrix #Synapse #Pixelfed #Help #Experience #VPS #Hetzner_de #OVH #DigitalOcean #Bunny_net #Services

  37. @frank Tchap is the name of the client, it's a rebrand of #Element (Belgium recently launched Beam -- same thing). From what I can see online, it looks like Tchap relies on #synapse instead of #tuwunel

  38. @frank Tchap is the name of the client, it's a rebrand of #Element (Belgium recently launched Beam -- same thing). From what I can see online, it looks like Tchap relies on #synapse instead of #tuwunel

  39. Boah. Ich hab am Wochenende meinen #Matrix Server komplett zerschossen... Kennt sich jemand damit aus? Würde gern versuchen die alten Daten wieder herzustellen. #Synapse #BackUp #Kaputtgefixt #ElementX

  40. I am looking for a possibility to bridge Matrix rooms to Signal groups. For our local #makerspace. Any hints appreciated!

    (I've researched that I could do it with setting up my own synapse homeserver with the right plugins, but I hope there is a simpler way for doing this...)

    #matrix #synapse #signal #askfedi

  41. I am looking for a possibility to bridge Matrix rooms to Signal groups. For our local #makerspace. Any hints appreciated!

    (I've researched that I could do it with setting up my own synapse homeserver with the right plugins, but I hope there is a simpler way for doing this...)

    #matrix #synapse #signal #askfedi

  42. Ok, so the issue is not in the databases. Their sizes are more or less acceptable. The issue is in media files from #Telegram bridge. Around 45 GB of media files are from public Telegram channels bridged to #Matrix.

    I suppose I need to tune media retention for #synapse.

    #homelab #selfhosting #selfhosted #selfhost

  43. Et hop, on rajoute une couche pour la soirée ! Pas de repos pour les braves, voici les dernières mises à jour tout juste déployées sur le cluster :

    #PasswordPusher mis à jour pour envoyer tes secrets de manière encore plus sécurisée 🔐
    #StirlingPDF passe à la vitesse supérieure pour tous tes besoins sur les PDF 📄
    #Synapse (Matrix) s'est refait une beauté en coulisses pour des discussions au top 💬