synapse部署

1: 环境准备

云服务器一台2c4g以上
域名一个申请好https证书

2: docker镜像准备

synapse(server): matrixdotorg/synapse:v1.129.0
element-web(web): vectorim/element-web:v1.11.101
synapse-admin(管理端): awesometechnologies/synapse-admin:0.11.1
livekit(视频通话): livekit/livekit-server:latest
auth-service(视频通话): ghcr.io/element-hq/lk-jwt-service:latest

3: 配置文件准备

livekit配置文件config.yaml
keys里的用户名和密码需要和docker-compose里设置的一致


port: 7880
bind_addresses:
  - "0.0.0.0"
rtc:
  tcp_port: 7881
  port_range_start: 50100
  port_range_end: 50200
  use_external_ip: false
  turn_servers:
    - host: xx.xxx.xyz
      port: 3478
      # tls, tcp, or udp
      protocol: udp
      # Livekit 配置第三方TURN服务不支持静态共享密钥
      # 用从 cloudflare api 中获取的用户名和凭证
      username: "xxxx"
      credential: "xxxx#xx0"
  #只使用 eth0(你的实际主网卡)生成 ICE 候选地址;排除掉所有虚拟 Docker 网桥和虚拟网卡
  interfaces:
    includes:
      - eth0
    excludes:
      - docker0
      - br-*
      - veth*
logging:
  level: info
turn:
  enabled: false
  domain: localhost
  cert_file: ""
  key_file: ""
  tls_port: 5349
  udp_port: 443
  external_tls: true
keys:
  admin: "admin1234"
signal_relay:
  retry_timeout: 60s
  min_retry_interval: 500ms
  max_retry_interval: 5s
  stream_buffer_size: 1000000
room:
  empty_timeout: 300

synapse-admin配置文件config.json


{
  "restrictBaseUrl": "https://chat.example.xyz"
}

element-web配置文件config.chat.example.xyz.json
修改base_url和server_name

m.identity_server作用(可以不用设置):用来做身份识别,方便通过email 手机号找到对方,找回密码等:https://github.com/matrix-org/sydent


{
    "default_server_config": {
        "m.homeserver": {
            "base_url": "https://chat.example.xyz",
            "server_name": "chat.example.xyz"
        },
        "m.identity_server": {
            "base_url": "https://chat.example.xyz"
        }
    },
    "disable_custom_urls": false,
    "disable_guests": true,
    "disable_login_language_selector": false,
    "disable_3pid_login": false,
    "force_verification": false,
    "brand": "Element",
    "integrations_ui_url": "https://scalar.vector.im/",
    "integrations_rest_url": "https://scalar.vector.im/api",
    "integrations_widgets_urls": [
        "https://scalar.vector.im/_matrix/integrations/v1",
        "https://scalar.vector.im/api",
        "https://scalar-staging.vector.im/_matrix/integrations/v1",
        "https://scalar-staging.vector.im/api",
        "https://scalar-staging.riot.im/scalar/api"
    ],
    "default_widget_container_height": 280,
    "default_country_code": "GB",
    "show_labs_settings": false,
    "features": {},
    "default_federate": true,
    "default_theme": "light",
    "room_directory": {
        "servers": ["https://xxx.xxxx.xyz"]
    },
    "enable_presence_by_hs_url": {
        "https://matrix.org": false,
        "https://matrix-client.matrix.org": false
    },
    "setting_defaults": {
        "breadcrumbs": true
    },
    "features": {
        "feature_video_rooms": true,
        "feature_group_calls": true,
        "feature_element_call_video_rooms": true
    },
    "element_call": {
        "use_exclusively": true,
        "participant_limit": 8,
        "brand": "Element Call"
    },
    "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
}

4: 生成synapse配置文件

SYNAPSE_SERVER_NAME指定自己的域名


docker run -it --rm -v /root/workspace/matrix/data:/data -e SYNAPSE_SERVER_NAME=chat.example.xyz -e SYNAPSE_REPORT_STATS=yes matrixdotorg/synapse:v1.129.0 generate

5: 修改synapse配置文件homeserver.yaml


以下这些是需要修改或者新增的
server_name
public_baseurl: "https://chat.example.xyz"
public_baseurl: https://houkunlin.cn 配置是为了告诉客户端我们 synapse 服务的真实通信地址,客户端会访问 https://houkunlin.cn/.well-known/matrix/client 拿到 {"m.homeserver":{"base_url":"https://houkunlin.cn/"}} 服务器地址信息。
serve_server_wellknown: true
serve_server_wellknown: true 配置实际主要是为了访问 https://houkunlin.cn/.well-known/matrix/server 路径内容返回 {"m.server":"houkunlin.cn:443"} 格式的内容,告诉其他服务器我的通信地址和端口
enable_registration: true
enable_registration_without_verification: true
public_baseurl: "https://chat.example.xyz"
serve_server_wellknown: true

turn_uris: ["turn:turn.xxxx.top:3478?transport=udp", "turn:turn.xxxxx.top:3478?transport=tcp", "turns:turn.xxxx.top:5349?transport=tcp"]
turn_username: "xxxx"
turn_password: "xxxx"
turn_allow_guests: false

下面这些是通话需要的配置
experimental_features:
  # MSC3266: Room summary API. Used for knocking over federation
  msc3266_enabled: true
  # MSC4222 needed for syncv2 state_after. This allow clients to
  # correctly track the state of the room.
  msc4222_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

rc_delayed_event_mgmt:
  # 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
  per_second: 1
  burst_count: 20
  • 完整配置:

# 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: "chat.example.xyz"
pid_file: /data/homeserver.pid
listeners:
  - port: 8008
    tls: false
    type: http
    x_forwarded: true
    resources:
      - names: [client, federation]
        compress: false
database:
  name: sqlite3
  args:
    database: /data/homeserver.db
log_config: "/data/chat.example.xyz.log.config"
media_store_path: /data/media_store
registration_shared_secret: "u;djb.Yjt1;vf;g+&.0SW^Tnhto^mdE9ekt6f6upYZz3ur-KXe"
report_stats: false
macaroon_secret_key: ":vyK@SB_g78s*E_nr41K&7B7sP;JTN,kxImS8Dkgioj9DLhAr^"
form_secret: "WJfe@jCp9DZqoaDRsnFIiJjDmu,lo0#jXfE*q~O,9Eu9meH*sf"
signing_key_path: "/data/chat.example.xyz.signing.key"
# 修改为你的服务端域名
trusted_key_servers:
  - server_name: "chat.example.xyz"

enable_registration: true
enable_registration_without_verification: true

public_baseurl: "https://chat.example.xyz"

serve_server_wellknown: true

turn_uris: ["turn:turn.xxxx.top:3478?transport=udp", "turn:turn.xxxxx.top:3478?transport=tcp", "turns:turn.xxxx.top:5349?transport=tcp"]
turn_username: "xxxx"
turn_password: "xxxx"
turn_allow_guests: false

#需要配合nginx上传的body请求体大小
max_upload_size: 200M
remote_media_download_burst_count: 1G
remote_media_download_per_second: 5M
#保存的过期时间
media_retention:
  local_media_lifetime: 90d
  remote_media_lifetime: 14d

#"all": any locally-created room
#"invite": any room created with the private_chat or trusted_private_chat room creation presets
#"off": this option will take no effect
encryption_enabled_by_default_for_room_type: all

#消息保留时间
retention:
  enabled: true
  default_policy:
    min_lifetime: 1d
    max_lifetime: 30d
  allowed_lifetime_min: 1d
  allowed_lifetime_max: 90d
  purge_jobs:
    - longest_max_lifetime: 3d
      interval: 12h
    - shortest_max_lifetime: 3d
      interval: 1d

experimental_features:
  # MSC3266: Room summary API. Used for knocking over federation
  msc3266_enabled: true
  # MSC4222 needed for syncv2 state_after. This allow clients to
  # correctly track the state of the room.
  msc4222_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

rc_delayed_event_mgmt:
  # 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
  per_second: 1
  burst_count: 20

# vim:ft=yaml

6: docker-compose文件准备

synapse需要创建好挂载目录


version: "3.3"

services:
  synapse:
    image: matrixdotorg/synapse:v1.129.0
    container_name: synapse
    restart: always
    ports:
      - 8008:8008
      - 8009:8009
      - 8448:8448
    volumes:
      - /root/workspace/matrix/data:/data
    environment:
      VIRTUAL_HOST: "chat.example.xyz"
      VIRTUAL_PORT: 8008
      LETSENCRYPT_HOST: "chat.example.xyz"
      SYNAPSE_SERVER_NAME: "chat.example.xyz"
      SYNAPSE_REPORT_STATS: "yes"
      TZ: Asia/Shanghai

  element-web:
    image: vectorim/element-web:v1.11.101
    container_name: element-web
    restart: always
    ports:
      - "8888:80"
    volumes:
      - /root/workspace/matrix/element/config.chat.example.xyz.json:/app/config.chat.example.xyz.json

  auth-service:
    image: ghcr.io/element-hq/lk-jwt-service:latest
    container_name: element-call-jwt
    hostname: auth-server
    environment:
      - LK_JWT_PORT=8080
      - LIVEKIT_URL=https://chat.example.xyz/livekit/sfu
      - LIVEKIT_KEY=admin
      - LIVEKIT_SECRET=admin1234
      - LIVEKIT_LOCAL_HOMESERVERS=chat.example.xyz
    restart: unless-stopped
    ports:
      - 8080:8080

  livekit:
    image: livekit/livekit-server:latest
    container_name: element-call-livekit
    command: --config /etc/livekit.yaml
    ports:
      - 7880:7880/tcp
      - 7881:7881/tcp
      - 50100-50200:50100-50200/udp
    restart: unless-stopped
    volumes:
      - /root/workspace/matrix/config.yaml:/etc/livekit.yaml:ro

  synapse-admin:
    container_name: synapse-admin
    image: awesometechnologies/synapse-admin:0.11.1
    ports:
      - "8181:80"
    volumes:
      - /root/workspace/matrix/admin/config.json:/app/config.json:ro
    restart: unless-stopped

7: 运行docker-compose


docker-compose up -d

8: 创建用户

-a代表是管理员


docker exec -it synapse register_new_matrix_user http://localhost:8008 -c /root/workspace/matrix/data/homeserver.yaml -a -u admin -p admin1234

9: nginx配置转发


server {
    listen       80;
    server_name  chat.example.xyz;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name chat.example.xyz;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    ssl_certificate      /etc/nginx/ssl/server2.crt;
    ssl_certificate_key  /etc/nginx/ssl/server2.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
    ignore_invalid_headers off;
    client_max_body_size 0;
    proxy_read_timeout 600s;

    error_page 403 404 500 502 503 504 /index.html;

    index index.htm index.html;

    # 访问 Element.io 的 WEB 客户端
    location / {
        # alias /var/www/matrix/;
        # try_files $uri $uri/ =404;
		proxy_pass http://x.x.x.x:8888;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
		add_header X-Frame-Options SAMEORIGIN;
		add_header X-Content-Type-Options nosniff;
		add_header X-XSS-Protection "1; mode=block";
		add_header Content-Security-Policy "frame-ancestors 'self'";
    }

    location = /.well-known/matrix/client {
    	return 200 '{"m.homeserver": {"base_url": "https://chat.example.xyz"},"org.matrix.msc4143.rtc_foci":[{"type":"livekit","livekit_service_url":"https://chat.example.xyz/livekit/jwt"}]}';
    	default_type application/json;
    	add_header Access-Control-Allow-Origin *;
    }

    # 把 /.well-known/ 和 /_matrix/ 路径下的请求都转发给后端服务器
    location ~ ^/(_matrix|.well-known|_synapse/admin)/ {
        proxy_pass                          http://x.x.x.x:8008;
        proxy_set_header Host               $http_host;
        proxy_set_header Upgrade            $http_upgrade;
        proxy_set_header Connection         "upgrade";
        proxy_set_header X-Proxy-Host       $proxy_host;
        proxy_set_header X-Forwarded-Host   $host;
        proxy_set_header X-Forwarded-Server $host:$server_port;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_ssl_protocols                 TLSv1.2 TLSv1.3;
    }

    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;

      # JWT Service running at port 8080
      proxy_pass http://x.x.x.x:8080/;
    }

    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://x.x.x.x:7880/;
    }

   #location  /synapse/admin/ {
        # alias /var/www/matrix/;
        # try_files $uri $uri/ =404;
     #   proxy_pass http://x.x.x.x:8181/;
     #   proxy_set_header Host $host;
     #   proxy_set_header X-Real-IP $remote_addr;
     #   add_header X-Frame-Options SAMEORIGIN;
     #   add_header X-Content-Type-Options nosniff;
     #   add_header X-XSS-Protection "1; mode=block";
     #   add_header Content-Security-Policy "frame-ancestors 'self'";
    #}
}

server {
    listen       80;
    server_name  admin.example.xyz;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name admin.example.xyz;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    ssl_certificate      /etc/nginx/ssl/cert.pem;
    ssl_certificate_key  /etc/nginx/ssl/key.pem;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
    ignore_invalid_headers off;
    client_max_body_size 0;
    proxy_read_timeout 600s;

    error_page 403 404 500 502 503 504 /index.html;

    index index.htm index.html;

    
    location  / {
        # alias /var/www/matrix/;
        # try_files $uri $uri/ =404;
        proxy_pass http://synapse-admin;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header Content-Security-Policy "frame-ancestors 'self'";
    }
}