ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

办公场景自建Matrix服务器:Synapse+Element私有化部署指南

办公场景自建Matrix服务器:Synapse+Element私有化部署指南 1. 项目概述与方案选型1.1 办公场景下为什么要自建 Matrix 服务器先说说这个项目到底解决了什么问题。办公室里装一套即时通讯工具表面上不难真正落地的时候你会发现一堆绕不开的坎公司内部的数据能不能不出内网、聊天记录归谁管、部门隔离怎么做、新人入职怎么批量开账号、文件传输有没有大小限制还有最现实的一点——Saas 产品按人头收费一年下来几十上百号人的费用真不便宜。Matrix 是这几年开源通讯领域绕不开的一个协议它最大的特点是开放和去中心化。用户之间的聊天记录不归某一个平台独有而是由一个个房间承载每个房间可以在任意一台服务器上落地。Synapse 就是 Matrix 协议最成熟的服务器端实现用 Python 写的部署在 Ubuntu 上配合 Element 这套客户端就能拼出一个完整的私有化办公通讯平台。这个方案适合谁适合那种数据必须留在自己手里的中小团队、项目组、实验室或者纯粹想给家里几台设备搭个内网聊天服务的折腾型选手。我不建议大几百人的企业用它替代企业微信或钉钉管理后台和审批流差得远但几十人以内、以技术协作和文件沟通为主的场景Synapse 完全可以胜任。1.2 为什么选 Synapse 而不选其他开源方案选型的时候我对比过几个路线现在的办公通讯开源方案其实不少但各自的侧重点差别很大。方案定位优势短板Synapse Element去中心化通讯协议实现开放协议、端到端加密、生态完整Python 实现、内存占用偏高Mattermost类 Slack 工作台界面熟悉、集成丰富数据模型偏企业流程协议封闭Rocket.Chat团队协作平台功能全、开箱即用部署较重定制不如 Matrix 灵活IRC 网盘传统极客方案极轻量、稳定无历史消息同步、无端到端加密当时我选 Synapse 的核心理由是三点。第一Matrix 协议本身是开放的意味着以后想换服务器端实现比如换 Dendrite客户端可以无缝迁移不会被绑死。第二房间模型特别适合办公场景——一个项目一个房间部门之间的隔离天然就能通过房间权限实现。第三Element 客户端的体验已经相当接近主流商业 IM 了大家切换过来的学习成本很低。当然也要说句公道话Synapse 不是省油的灯Python 写的服务端在内存占用上确实偏大官方也一直在推下一代实现 Dendrite但论功能完整度、文档成熟度和踩坑资料的数量Synapse 目前依然是自建 Matrix 服务器的首选。2. 部署前的环境准备2.1 硬件配置与 Ubuntu 版本选择先说结论一台 2 核 4G 内存的机器跑 Synapse带三十人左右的日常办公完全够用。网上很多教程说 1G 内存就能跑那是指纯实验环境真上了办公场景Element 客户端轮询、媒体文件转存、数据库连接池一起上来1G 内存会频频触发 OOM。我实际部署的这台机器是 4 核 8G日常负载很轻松extra headroom 还能顺便跑个 coturn 转服务器。操作系统建议直接上 Ubuntu 24.04 LTS或者保守一点用 22.04 LTS。LTS 版本意味着五年的安全更新对于要长期跑的服务来说这是底线。新装系统的话顺手确认一下 Python 版本Synapse 目前要求 Python 3.11 以上Ubuntu 24.04 自带的就是 3.12不用额外折腾。磁盘规划是个容易被忽略的坑。Matrix 的媒体文件图片、文件、头像默认都存在本地 media_store 目录里日积月累非常占空间。建议单独给 /var/lib/matrix-synapse 分一个数据盘或者至少确保所在分区有足够的余量。我见过有人把服务装在 20G 的系统盘上跑了三个月磁盘 100%整个服务直接瘫痪。2.2 网络规划与基础系统配置本地网络版的核心是不出网所以网络规划要提前想清楚。首先给服务器设置一个静态内网 IP比如 192.168.1.10避免 DHCP 重新分配导致客户端连不上。其次要决定 server_name这是 Matrix 世界里的身份标识客户端登录的时候要填这个。没有公网域名的话可以直接用服务器的内网 IP 或者机器名比如 office-server只要保持整个局域网内统一就行。系统层面的准备工作我建议按这个顺序过一遍# 更新软件源并安装基础工具 sudo apt update sudo apt upgrade -y sudo apt install -y curl gnupg lsb-release nginx # 设置时区避免日志时间和实际时间对不上 sudo timedatectl set-timezone Asia/Shanghai # 确认主机名建议改一个有意义的名字 sudo hostnamectl set-hostname office-server # 查看 IP确认静态地址已生效 ip addr show很多人部署完服务才发现日志时间不对、或者客户端连不上很大一部分原因是宿主机的基础设置没弄干净。SSH 连不上的话先确认 openssh-server 是否安装sudo apt install -y openssh-server sudo systemctl enable --now ssh防火墙这块如果公司内网本身有统一的出口管控内网服务之间通常不用额外开防火墙但如果你在服务器上启用了 ufw记得放行 Synapse 和后续依赖的端口。我先说端口规划后面配置的时候会对应上端口用途8008Synapse 主监听端口HTTP8448联邦通信端口本地版可不开3478/5349TURN 服务的 UDP/TCP 端口音视频用49152-49200TURN 媒体传输的 UDP 端口段2.3 域名还是 IP本地网络版的关键取舍这里值得单独说一下。Matrix 协议设计上是面向公网的去中心化网络server_name 通常是域名比如 example.com。但本地网络版不需要对外提供联邦服务因此有一个取巧但也完全合规的做法server_name 直接写内网 IP 或者内网主机名。选择的时候注意一点server_name 写入配置之后客户端和服务器之间的交互都会以它为基础。如果你以后可能把这个服务暴露到公网、或者要和其他 Matrix 服务器联邦互通那 best practice 是用一个有 DNS 解析的域名。但如果确认一辈子只在局域网里跑用 IP 当 server_name 最省事省去了改配置的麻烦。唯一要提醒的是Element 客户端在部分浏览器里对纯 IP 的 server_name 有些小脾气比如密码存储策略会更保守这个后面章节我会给解决办法。3. 安装 Synapse 服务器的两种常用路径3.1 官方 apt 仓库安装推荐Synapse 官方提供了 Debian/Ubuntu 的 apt 仓库这是我最推荐的方式——它把 Python 依赖、systemd 服务文件、默认配置模板都打包好了升级也方便不用自己维护一套 Python 虚拟环境。# 添加官方仓库 sudo apt install -y apt-transport-https sudo curl -fsSL https://packages.matrix.org/debian/matrix-org.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/matrix-org.gpg echo deb [signed-by/usr/share/keyrings/matrix-org.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main | sudo tee /etc/apt/sources.list.d/matrix-org.list # 安装 sudo apt update sudo apt install -y matrix-synapse-py3安装过程中会提示输入 server_name 并选择是否上报匿名统计。server_name 就填我们在网络规划阶段确定的那个值比如 office-server。如果安装时手滑填错了也没关系后面改 homeserver.yaml 就行。apt 方式装好之后synapse 用户、/etc/matrix-synapse 配置目录、/var/lib/matrix-synapse 数据目录都已经自动创建好了省心不少。3.2 pip 方式安装适合喜欢完全掌控的环境如果你的服务器系统不是 Debian 系、或者想跑最新预发布版本pip 方式也完全可行。核心思路是先用 venv 建独立 Python 环境再把 Synapse 装进去避免污染系统 Python。# 安装 Python 虚拟环境工具和编译依赖 sudo apt install -y python3-venv python3-dev libffi-dev build-essential libssl-dev # 建目录和虚拟环境 sudo mkdir -p /opt/matrix-synapse sudo chown $USER:$USER /opt/matrix-synapse python3 -m venv /opt/matrix-synapse/env source /opt/matrix-synapse/env/bin/activate # 安装 Synapse pip install --upgrade pip pip install matrix-synapsepip 装完之后需要用官方提供的生成配置文件脚本手动初始化source /opt/matrix-synapse/env/bin/activate python -m synapse.app.homeserver \ --server-name office-server \ --config-path /opt/matrix-synapse/homeserver.yaml \ --generate-config \ --data-directory /opt/matrix-synapse/data \ --report-statsno这两种方式我实测下来apt 版升级最省心sudo apt upgrade就完事了pip 版适合需要跑特定版本或者改源码的场景。个人建议生产环境一律走 apt。3.3 数据库配置为什么生产环境必须用 PostgreSQLSynapse 默认用 SQLite单文件数据库零配置跑测试完全没问题。但办公场景多人并发时SQLite 的写锁会变成明显的瓶颈尤其是存在大量事件写入的房间检索会越来越慢。官方文档也明确说了生产环境用 PostgreSQL。sudo apt install -y postgresql postgresql-contrib # 切换到 postgres 用户创建 Matrix 专用账号和库 sudo -u postgres psql EOF CREATE USER matrix WITH PASSWORD 这里换成你自己的强密码; CREATE DATABASE matrix ENCODING UTF8; GRANT ALL PRIVILEGES ON DATABASE matrix TO matrix; EOF然后在 homeserver.yaml 里把数据库配置改掉database: name: psycopg2 args: user: matrix password: 这里换成你自己的强密码 database: matrix host: localhost port: 5432 cp_min: 5 cp_max: 10改完配置重启 Synapse 之前建议先验证一下连接PGPASSWORD这里换成你自己的强密码 psql -h localhost -U matrix -d matrix -c SELECT version();看到 PostgreSQL 版本号就说明数据库通路没问题。这里有个细节cp_min 和 cp_max 控制连接池大小办公场景 5 到 10 足够不用贪多连接数太高反而给 PostgreSQL 增加无谓的开销。4. 核心配置与本地化设置4.1 homeserver.yaml 关键参数解读安装完成后的核心工作就是改 homeserver.yaml这个文件是 Synapse 的命脉。默认模板生成的配置往往偏保守或者偏公网场景我们按本地网络版的需求逐项调整。先看最重要的几个参数# 服务器标识客户端登录时填这个名字 server_name: office-server # 监听配置默认监听 8008改为监听所有内网接口 listeners: - port: 8008 type: http bind_addresses: [0.0.0.0] tls: false x_forwarded: false resources: - names: [client, federation] compress: true # 本地网络版不需要联邦关闭对外联系 enable_registration: false registration_shared_secret: 用 openssl rand -base64 48 生成一串 # 关闭联邦功能防止内网服务器主动外连 federation_enabled: false重点解释一下 registration_shared_secret 的作用。它是一把注册签名密钥配合官方提供的register_new_matrix_user脚本可以不用开放注册就能创建账号。这在办公场景下特别实用——不允许员工随便注册但管理员又能随时批量开号。监听地址配置成 0.0.0.0 是为了让局域网内其他设备能通过服务器 IP 访问 8008 端口。如果你只在服务器本机测试用 127.0.0.1 也行。4.2 启动服务并纳入 systemd 管理apt 方式安装后systemd 服务已经自动创建好了服务名是matrix-synapse。改完配置直接:sudo systemctl enable matrix-synapse sudo systemctl restart matrix-synapse sudo systemctl status matrix-synapse看到active (running)就说明起服务了。验证服务是否正常最直接的办法是请求一下健康检查接口:curl http://localhost:8008/_matrix/client/versions curl http://localhost:8008/health第一条命令返回一串 JSON里面列出了客户端 API 支持的版本号第二条命令返回{status: OK}之类的健康状态。如果 curl 没反应先看日志:sudo journalctl -u matrix-synapse -f如果是 pip 方式安装的需要自己写 systemd 服务文件。我把常用的 unit 配置贴在下面注意路径按实际安装位置调整[Unit] DescriptionMatrix Synapse Afternetwork.target postgresql.service [Service] Usersynapse Groupsynapse WorkingDirectory/opt/matrix-synapse EnvironmentFile-/etc/default/matrix-synapse ExecStart/opt/matrix-synapse/env/bin/python -m synapse.app.homeserver --config-path/opt/matrix-synapse/homeserver.yaml Restarton-failure RestartSec5s [Install] WantedBymulti-user.target4.3 Element Web 客户端的部署方式Matrix 官方推荐的 Web 客户端是 Element用户打开浏览器输入地址就能用。它的部署方式很简单把静态文件拉到 Nginx 的 web 目录再做一个简单反代就行。# 下载 Element Web 最新版注意替换版本号 cd /var/www sudo wget https://github.com/element-hq/element-web/releases/download/v1.11.70/element-v1.11.70.tar.gz sudo tar -xzf element-v1.11.70.tar.gz sudo mv element-v1.11.70 element然后写一个 Nginx 站点配置把 /var/www/element 作为根目录同时把 /_matrix 路径反向代理到本机的 Synapse 8008 端口server { listen 80; server_name office-server; root /var/www/element; index index.html; # Element 是单页应用所有未命中路径都返回 index.html location / { try_files $uri $uri/ /index.html; } # Matrix 客户端 API 反向代理到 Synapse location /_matrix { proxy_pass http://127.0.0.1:8008; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }为什么需要 Nginx直接让用户访问 8008 端口其实也能用但有三个问题一是客户端 API 和 Web 静态资源混杂在同一个端口上二是不方便控制上传大小三是以后要加 HTTPS 证书时候没有入口。走一层 Nginx 反代权限控制、限流、日志全部都统一了。4.4 通过 Nginx 统一暴露 Synapse 与 Element上面那段配置已经包含了反代但还有个细节要处理Element Web 默认的配置地址。Element 有个配置文件 config.json可以指定它默认连接哪个 homeserver这样用户在登录页就不用手动填服务器地址了。sudo nano /var/www/element/config.json典型配置如下{ m.homeserver: { base_url: http://office-server:8008 }, m.identity_server: { base_url: http://office-server:8008 }, default_server_config: { m.homeserver: { base_url: http://office-server:8008, server_name: office-server } } }如果 Element 是通过 Nginx 访问的同源路径也就是浏览器地址是 http://office-server而 API 也走同一主机的 /_matrixbase_url 可以留空字符串让浏览器自动用当前域名。但本地网络版经常出现大家用 IP 访问的情况服务器名又是主机名所以显式写上 base_url 最稳。5. 办公场景落地配置细节5.1 账号创建与注册策略前面把 enable_registration 设成了 false现在需要手动创建账号。官方提供了一个命令行工具# 进入虚拟环境apt 方式服务端自带了 sudo -u matrix-synapse register_new_matrix_user \ -c /etc/matrix-synapse/homeserver.yaml \ -u zhangsan \ -p 初始密码 \ -a这里有个小坑register_new_matrix_user 这个命令在 apt 安装时默认放在 /usr/bin 下但你要是用的自定义数据目录注意-c参数一定要指向实际使用的配置文件否则工具会拿着默认配置去读注册密钥结果对不上数据库报各种奇怪的错。-a参数表示让这个用户成为管理员。管理员账号以后有什么用在 Element 界面里可以管理所有房间、查看服务器状态、踢人、封号。办公场景建议至少创建两个管理员账号一个日常用一个留作应急备用避免把鸡蛋放一个篮子里。账号多了之后逐个手工创建显然不现实。Synapse 提供了 admin API支持通过 HTTP 调用创建用户。写个简单的批量脚本从 Excel 或 CSV 里读姓名和工号循环调用 API 就能实现批量开户# 先获取管理员 access_token curl -s http://localhost:8008/_matrix/client/v3/login \ -X POST \ -d {type:m.login.password,user:zhangsan,password:初始密码} \ -H Content-Type: application/json # 拿到 token 后批量创建用户 curl -s http://localhost:8008/_synapse/admin/v2/users/lisi:office-server \ -X PUT \ -d {password:初始密码,displayname:李四,admin:false} \ -H Authorization: Bearer $TOKEN \ -H Content-Type: application/json5.2 音视频通话少不了 TURN 服务器这是最容易被人忽略的一块。Element 客户端之间的文字聊天走 Synapse 的 8008 端口就够了但语音和视频通话走的是 WebRTC需要一套 TURN 服务器来打洞和转发媒体流。不配 TURN 的话很多在复杂网络环境下的办公室多层 NAT、统一出口代理会出现能看到对方在线一打电话就卡死的情况。coturn 是搭配 Synapse 最常用的 TURN 实现sudo apt install -y coturn配置 /etc/turnserver.conf关键配置如下listening-port3478 tls-listening-port5349 fingerprint lt-cred-mech use-auth-secret static-auth-secret用 openssl rand -base64 32 生成 realmoffice-server total-quota300 stale-nonce600然后把这个 static-auth-secret 同步到 homeserver.yaml 的 turn 配置段turn_uris: - turn:office-server:3478?transportudp - turn:office-server:3478?transporttcp turn_shared_secret: 和 turnserver.conf 保持一致的那串密钥 turn_allow_guests: true另外记得在防火墙里放行端口。很多办公室网络环境对 UDP 限制很严NTP、QUIC 都受影响WebRTC 恰恰主要走 UDP所以一旦发现音视频质量差先查 UDP 通不通。放行命令如下sudo ufw allow 3478/udp sudo ufw allow 3478/tcp sudo ufw allow 5349/udp sudo ufw allow 5349/tcp sudo ufw allow 49152:49200/udp5.3 文件上传大小与媒体存储策略办公场景离不开传文件Element 默认上传限制是 50MB这个数值在 Synapse 的配置里是max_upload_size单位是字节。要放宽到 200MB在 homeserver.yaml 里加一行max_upload_size: 200M注意Synapse 支持50M这种简写。但真正卡文件的通常是 Nginx 那一层默认client_max_body_size只有 1MB不配置的话大文件传一半会被 Nginx 直接断开连接。所以在 Nginx 的 server 块里加client_max_body_size 200m;媒体文件存储路径是media_store_path默认在数据目录下。建议定期用du -sh看看这个目录的占用我跑了一个季度之后发现头像、截图、文档附件加起来已经接近 20GB这个增长速度在办公场景是很正常的。6. 常见问题与排查实录6.1 日志查看与基础排查方法Synapse 出问题第一件事就是看日志。apt 装的服务日志走 systemd:sudo journalctl -u matrix-synapse -n 200同时还有一个独立的应用日志 homeserver.log路径通常在 /var/log/matrix-synapse 下。这个日志会记录从客户端 API 请求到联邦事件处理的完整信息。调试的时候建议把日志级别临时调低在 homeserver.yaml 里log_level: DEBUG调试完记得改回 INFO不然日志量会非常惊人半天就能写满一个 G。6.2 高频问题速查表我把自己从部署到日常维护踩过的坑整理成一张表基本覆盖了 80% 的常见问题。现象可能原因排查方法解决办法curl localhost:8008 无响应Synapse 服务没起来journalctl 看进程日志查配置语法或 Python 版本客户端提示服务器不可用防火墙拦了 8008 端口telnet 服务器IP 8008ufw 放行或在路由器/交换机上开放端口登录报 403server_name 填错了看 homeserver.log 的注册报错用正确格式用户名:server_name登录注册用户提示未知错误registration_shared_secret 不一致检查 yaml 配置和命令读取的是否同一文件统一配置文件路径语音视频无法建立TURN 未配置或 UDP 被禁浏览器控制台看 WebRTC 日志配置 coturn 并放行 UDP 端口段上传大文件失败Nginx client_max_body_size 限制看 Nginx 错误日志返回 413调大该参数内存持续走高媒体转码或大量并发同步top看进程内存增加内存或限制连接池数据库连接被拒绝PostgreSQL 认证配置不对用 psql 手动连检查 pg_hba.conf 和 yaml 的密码6.3 亲自踩过的几个坑第一个大坑是默认用 IP 当 server_name 的浏览器密码问题。Element 是个 Web 应用在纯 HTTP 环境下浏览器对密码框的自动填充策略非常保守——很多同事反映密码输入框不提示保存。这个没法根治只要内网不开 HTTPS 就会存在。我的做法是建议团队用桌面端 Element低频场景用 Web 版毕竟桌面端没有这个限制。第二个坑是 SQLite 转 PostgreSQL 时机的选择。我一开始图省事用 SQLite 跑了两周二十几个人聊天没什么问题。后来数据量到了几万条事件每次打开房间都要卡一下。迁移本身不算难官方提供了脚本synapse_port_db但迁移期间服务必须停如果你用 SQLite 跑了很久、已经有大量媒体文件迁移的耗时和风险都会增加。所以建议从一开始就上 PostgreSQL不要留这个后患。第三个坑是系统重启之后 coturn 没起来。coturn 安装后默认是 disabled 状态需要手动 enable否则服务器重启后 TURN 服务不会自动启动第二天所有人语音全挂。这个坑特别隐蔽因为文字聊天一切正常只有打电话才暴露。记得执行sudo systemctl enable coturn sudo systemctl restart coturn sudo systemctl status coturn还有一个经验是备份策略。Synapse 的数据包括三部分PostgreSQL 数据库、媒体文件的 media_store 目录、以及 homeserver 的配置文件。数据库每天凌晨 dump 一次media_store 可以做增量同步。我写了一个简单 cron 做数据库备份30 3 * * * PGPASSWORD密码 pg_dump -h localhost -U matrix matrix | gzip /backup/matrix-$(date \%F).sql.gz媒体文件比数据库大得多每天全量备份不现实我用的 rsync 增量同步到另一台服务器或移动硬盘上。7. 本地化部署的长期运维心得7.1 资源监控与日常巡检Synapse 跑稳之后日常运维其实很轻但有几个指标值得盯一盯。内存是大头Synapse 是 Python 写的单进程多协程应用内存使用量会随着房间数和在线用户数波动。建议配一个简单的监控脚本或者用现成的 node_exporter 把指标推到监控面板里。磁盘是另一个重点。media_store 目录的增量速度取决于团队的使用习惯如果同事们习惯在群里发截图和文档一个月几个 GB 非常正常。我给自己定的规则是每周一早晨看一眼df -h低于 30% 剩余空间就启动清理流程。Synapse 没有内置的媒体过期删除功能要清旧文件得自己写脚本调 admin API比较麻烦所以更推荐从一开始就规划好磁盘容量。7.2 后续可以扩展的方向这套系统跑起来之后如果想往更完整的办公平台方向发展有几个比较容易落地的扩展。接入 LDAP 或 AD 域控员工用公司账号直接登录 Matrix账号注销时自动禁用。启用户注销与数据清理策略配合管理员 API 实现离职员工的账号回收。部署 nginx 反向代理时顺手加一套 HTTPS 证书浏览器密码管理和安全性立刻上一个台阶。这些都是基于现有架构可以平滑演进的功能不会推翻重来。如果团队后续扩大到上百人或者对性能要求更高可以考虑把 TURN 和 Synapse 拆到不同机器Synapse 本身也可以做多实例扩展。但那是另一个量级的问题至少对于二三十人的办公网络这篇文章里这套方案已经非常够用了。最后说一点个人体会自建通讯系统最大的价值不是省钱而是把你对数据在哪里、谁能看到、谁能删这件事的控制权拿回来了。Matrix 的开放协议意味着今天用 Synapse明天也能切换到其他实现数据永远是你的。这个自由度是商用 SaaS 给不了的。这套部署方案我前后调试了两三天踩完坑总结下来其实真正动手配置的部分就那么几个文件趁周末在虚拟机上走一遍流程你会发现它远没有想象中复杂。
返回列表