抗疫期间,网络流量激增,团队协作通讯软件slack也变得很卡,偶尔还会掉线。是时候考虑自己部署一个开源替代品了,在比较了zulip,mattermost,rocketchat后最终选择了mattermost,并放在了子目录中与其他服务共存。

需求

如果图省事可以选择slack,或Microsoft Teams,只是这样你的数据除了团队成员外,服务提供商的工程师亦可查阅,而且特殊时期可能会碰到卡顿的情况(当然巨硬的Teams应该还是很稳健的)。
这里简单比较一下三个开源的同类软件zulip,mattermost,rocketchat。
注:由于是通讯服务,故需选择24*7可靠性较高的服务器。

zulip

👍提供免费试用,但搜索功能受限制
👍支持中文
👍全平台支持,包括浏览器。
👍插件丰富
👍对话可折叠,类论坛形式组织信息流
👍后端为Django(python3),前端用JS编写,数据库仅支持PostgreSQL
👎建议在全新系统上部署,不建议和其他服务共用,没有官方卸载脚本
👎必须部署在域名根目录,不支持子目录
👎docker-zulip为试验阶段,不适合生产环境部署
其实试用过后我是比较倾向用zulip的,信息管理逻辑和slack类似,但官方脚本是设计在全新系统上部署的,无法与其他服务共用,跑了脚本后不仅无法正常安装,且已有服务也受影响,逆向操作还原费了点功夫。之后分析了脚本,手动安装踩了不少坑,能用但今后维护并不方便。

Mattermost

👍提供demo试用,仅体验普通用户功能
👍支持中文
👍全平台支持,包括浏览器。
👍插件丰富
👍后端为Go,前端用React(JS),数据库支持MySQL和PostgreSQL
👍mattermost-docker
👎对话不可折叠
由于用Go编写,没有复杂的依赖关系,部署比较简单,且插件支持亦很丰富,所以选择了这个方案。

Rocket.Chat

👍提供14天免费试用
👍支持中文
👍全平台支持,包括浏览器。
👍docker-compose
👍插件丰富
👍使用Meteor(JS)框架编写,数据库仅支持MongoDB

每个团队的需求都不一样,所以先利用上述软件在线试用一段时间,看看有无自身急需的特性,必要插件的支持情况,维护人员技术栈是否切合等等再做最终决定。

部署Mattermost

mysql

安装mysql
创建数据库。记得把mmuser-password换掉。

1
2
3
create user 'mmuser'@'localhost' identified by 'mmuser-password';
create database mattermost;
grant all privileges on mattermost.* to 'mmuser'@'localhost';

安装Mattermost服务端

下载,将5.21.0换成当前最新稳定版

1
2
3
wget https://releases.mattermost.com/5.21.0/mattermost-5.21.0-linux-amd64.tar.gz
tar -xvzf mattermost*.gz
sudo mv mattermost /opt

创建数据文件夹,将/opt/mattermost/data换成挂载大容量硬盘的路径。

1
sudo mkdir /opt/mattermost/data

创建mattermost用户和设定相关文件夹权限。

1
2
3
sudo useradd --system --user-group mattermost
sudo chown -R mattermost:mattermost /opt/mattermost
sudo chmod -R g+w /opt/mattermost

编辑配置文件/opt/mattermost/config/config.json。这里SiteURL设置的是将mattermost置于非常规端口8443和域名子目录mattermost下,可按需更改。

1
2
3
"SiteURL": "https://example.com:8443/mattermost/",
"DriverName": "mysql",
"DataSource": "mmuser:mmuser-password@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8\u0026readTimeout=30s\u0026writeTimeout=30s",

编写系统服务文件

测试是否运行正常。

1
sudo -u mattermost /opt/mattermost/bin/mattermost

若无误输出会显示Server is listening on :8065
新建/lib/systemd/system/mattermost.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Unit]
Description=Mattermost
After=network.target
After=mysql.service
Requires=mysql.service

[Service]
Type=notify
ExecStart=/opt/mattermost/bin/mattermost
TimeoutStartSec=3600
Restart=always
RestartSec=10
WorkingDirectory=/opt/mattermost
User=mattermost
Group=mattermost
LimitNOFILE=49152

[Install]
WantedBy=mysql.service

启用mattermost服务。

1
2
3
sudo systemctl daemon-reload
sudo systemctl start mattermost.service
sudo systemctl enable mattermost.service

这里假定服务器的内网IP为192.168.1.2。浏览器打开http://192.168.1.2:8065
创建用户,首个用户具有system_admin权限,故先在内网建立确保服务器安全。其他配置等反向代理设好后在公网再设。

nginx

nginx的安装和配置可参考这篇文章nginx作为前端配合apache作为后端
我们这里无需用到apache,仅用nginx作为反向代理即可。
编辑/etc/nginx/sites-available/example.comSSL在nginx处配置而不是mattermost服务端
另外反代apache的相关配置已省去,与mattermost并不冲突。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
upstream mattermost {
server 192.168.1.2:8065;
keepalive 32;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;

server {
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}

server {
listen 8443 ssl http2;
listen [::]:8443 ssl http2;
server_name example.com;

client_max_body_size 0;
underscores_in_headers on;

ssl on;
ssl_certificate /etc/apache2/ssl/fullchain.cer;
ssl_certificate_key /etc/apache2/ssl/private/example.com.key;
ssl_session_timeout 1d;
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;

# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

location ~ /mattermost/api/v[0-9]+/(users/)?websocket$ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 50M;
proxy_set_header Host $http_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_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
client_body_timeout 60;
send_timeout 300;
lingering_timeout 5;
proxy_connect_timeout 90;
proxy_send_timeout 300;
proxy_read_timeout 90s;
proxy_pass http://mattermost;
}

location /mattermost/ {
client_max_body_size 50M;
proxy_set_header Connection "";
proxy_set_header Host $http_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_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
proxy_read_timeout 600s;
proxy_cache mattermost_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 2;
proxy_cache_use_stale timeout;
proxy_cache_lock on;
proxy_http_version 1.1;
proxy_pass http://mattermost;
}
}

网页配置Mattermost

浏览器访问https://example.com:8443/mattermost/,登录刚才创建的管理员帐号。进入System Console
ENVIRONMENT-SMTP处设置邮件服务器,不要用163邮箱,会被判定为垃圾邮件554 DT:SPM。可用阿里云的企业邮箱新建一个子帐号专门用来发信,地址和端口相关设置。保存后才点击Test Connection测试发信,正常的话管理员用户注册邮箱会收到测试邮件。
ENVIRONMENT-File Storage处设置图片和附件保存位置。

卸载Mattermost

停止并禁用mattermost服务。

1
2
3
sudo service mattermost stop
sudo systemctl disable mattermost
sudo rm /lib/systemd/system/mattermost.service

(可选)删除文件夹,删掉数据库。

1
2
3
sudo rm -rf /opt/mattermost
sudo mysql
DROP DATABASE mattermost;

参考资料

Installing Mattermost on Ubuntu 18.04 LTS
Mattermost Administrator’s Guide