【实用的开源工具】Tailchat:能装插件的自托管即时通讯
「实用的开源工具」系列:我只收集值得用的开源项目,写清楚它能做什么、怎么部署、有哪些坑,并在文末标明出处。内容整理自官方文档,核对日期 2026-10-31,具体版本以官方为准。文中的命令和配置都来自官方文档与官方仓库,我没有在自己的机器上逐条跑过,请先在测试环境走一遍。
项目信息卡
| 项目 | 说明 |
|---|---|
| 名称 | Tailchat |
| 做什么 | 开源的即时通讯应用,主打“插件”和“自己的工作空间”,官方称之为 noIM(Not only IM) |
| 许可证 | Apache-2.0 |
| 仓库 | github.com/msgbyte/tailchat |
| 官方文档 | tailchat.msgbyte.com |
| 最近版本 | v1.11.18(2026-10-02 发布,查询于 2026-10-31);仓库最近一次推送也是 2026-10-02,未归档 |
| 镜像 | Docker Hub 的 moonrailgun/tailchat,我查到 1.11.18 这个标签存在 |
| 依赖 | MongoDB、Redis、MinIO(官方 Compose 已包含),前面还有一个 Traefik 做路由 |
| 配置建议 | 官方推荐最低 1 核 2G |
| 稳定性提示 | README 写明:核心功能处于稳定阶段,但对第三方开发者开放的接口仍在完善,大体向后兼容,但保留破坏性变更的可能 |
它能做什么
下面这些是官方 README 和文档介绍里写到的能力:
- 群组空间:两级结构,群里再用面板划分话题;官方强调“只有被邀请的成员才能加入群组”,加好友需要昵称加一串随机数字。
- 插件系统:前端是微内核加插件,官方文档的功能列表里有自定义主题、网页嵌入面板、GitHub 通知订阅等。
- 常规聊天能力:提及、富文本、Markdown、表情回应、文件和图片分享、语音和视频通话。
- 权限与管理:群内角色(RBAC)、用户禁言、邮箱验证与找回密码,另有一个管理后台。
- 开放平台:官方文档列出了 Openapi、机器人和 OAuth。
- 后端是微服务结构,官方说明为集群部署做了准备;个人和小团队用一套 Compose 就够了。
不太适合的场景:只想要“装完就能用的普通聊天室”。它由好几个容器组成(核心服务、开放平台、插件服务、数据库、缓存、对象存储、路由),资源和运维都比单容器工具重。
部署
官方文档推荐用 Docker Compose。官方推荐的最低配置是 1 核 2G。
1. 准备目录,下载配置文件
官方的做法是从仓库直接下载两个文件:
mkdir -p /opt/tailchat && cd /opt/tailchat
wget https://raw.githubusercontent.com/msgbyte/tailchat/master/docker-compose.yml
wget https://raw.githubusercontent.com/msgbyte/tailchat/master/docker-compose.env2. 拉取镜像并改标签
仓库里的 docker-compose.yml 里写的是 image: tailchat,同时带着 build(从源码构建)。官方给的“用公共镜像”的做法,是拉下来再改成 tailchat 这个名字:
docker pull moonrailgun/tailchat:1.11.18
docker tag moonrailgun/tailchat:1.11.18 tailchat这是我按官方“指定版本”的写法固定了版本号(官方文档里的例子是 1.8.4,写的是同样的 pull 加 tag 两步)。官方说可以去 Docker Hub 查有哪些版本,请以实际存在的标签为准。
另外,官方也提供了命令行工具:npx tailchat-cli docker update 可以一键拉取/更新镜像,npx tailchat-cli docker init 会交互式地生成配置文件。这需要服务器上有 Node 环境(官方建议 16 以上),不想装 Node 的话用上面的手动方式即可。
3. 修改 docker-compose.env
官方文档明确建议修改这两项:
API_URL:对外可访问的地址,用于文件服务访问;官方说如果图片发出去显示不出来,就是这个没设。SECRET:服务端加密密钥,用来生成 Token。官方环境变量表写明默认值是tailchat,这是公开的,生产环境必须换成长随机字符串,否则任何人都可以伪造用户令牌。
注意:仓库里的 docker-compose.env 里 API_URL 的示例值是项目作者自己的演示站域名,SECRET 是空的,所以都要自己填。示例(域名请换成自己的):
API_URL=https://chat.example.com
SECRET=这里填一段足够长的随机字符串随机字符串可以用 openssl rand -hex 32 生成(这是通用做法,不是官方文档里的命令)。
其他配置项也在这个文件里,比较常用的有:
| 变量 | 说明(出自官方环境变量表) |
|---|---|
SMTP_SENDER、SMTP_URI | 配置邮件服务,用于找回密码、邮箱验证等 |
EMAIL_VERIFY | 设为 1 或 true,注册时增加邮箱验证 |
FILE_LIMIT | 文件和图片上传大小限制,默认 1048576(1MB),单位是字节 |
DISABLE_USER_REGISTER | 设为 1 或 true 关闭用户注册 |
DISABLE_GUEST_LOGIN | 关闭访客登录 |
DISABLE_CREATE_GROUP | 关闭用户创建群组 |
DISABLE_TELEMETRY | 关闭向项目方发送的匿名遥测 |
REGISTER_IP_LIMIT_PER_HOUR、REGISTER_IP_LIMIT_PER_DAY | 每个 IP 的注册次数限制,默认 3 次/小时、10 次/天 |
修改后的生效方式:改完 docker-compose.env 直接 docker compose up -d。个别配置会进缓存(比如 FILE_LIMIT 要发给客户端),官方列出了清缓存的办法:docker compose down 再 up -d(因为 Redis 没有持久化,相当于全新环境),或进管理后台点“清理配置缓存”。
4. 只让反向代理访问
官方 Compose 里 Traefik 的端口写的是:
ports:
- 11000:80
- 127.0.0.1:11001:808011000 没有绑定地址,会对所有网卡开放;而 11001 是 Traefik 的 API 面板,官方文件里已经绑在 127.0.0.1 了。如果前面要套 Nginx,我建议把第一行改成:
- 127.0.0.1:11000:80这是我的调整,不是官方默认值。官方 Compose 里 MongoDB、Redis、MinIO 都没有映射端口,只在内部网络里。
5. 启动
docker compose up -d
docker compose ps按官方说明,直接访问 http://<服务器IP>:11000 就能打开 Tailchat(有的云服务商需要手动放行防火墙端口)。如果你按上一步绑到了 127.0.0.1,就在服务器本机访问,或者先配好下面的 Nginx 再用域名访问。
数据放在 Docker 卷里:MongoDB 的卷叫 data,MinIO 的卷叫 storage。官方文档给的查看命令是:
docker volume ls | grep "tailchat-server"实际卷名会带上你的 Compose 项目名前缀(通常是目录名),所以上面的过滤词按你的目录名调整。
反向代理
官方说 Tailchat 的部分功能强依赖 HTTPS,比如音视频通话、嵌入外部的 HTTPS 媒体和网页;为了用户到服务器之间的安全,也强烈建议对外提供 HTTPS。
用 Nginx 的话,官方排障文档给的参考配置是这样的,关键是 WebSocket 的两个头:
server {
server_name chat.example.com;
listen 443 ssl;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_pass http://127.0.0.1:11000/;
}
}两点补充:
- 官方说,缺了 WebSocket 配置的症状是“能注册,但进不了主界面”。
- 官方还提供了一套用 swag 自动申请证书的 HTTPS 网关(
docker/swag.yml、docker/swag.env.example、docker/config/nginx.conf),适合服务器上没有占用 80/443 的情况。里面把swag.env的URL设成你的域名,再docker compose -f ./swag.yml up -d即可。它的 Nginx 配置是转发到127.0.0.1:11000的,所以如果用它,上一步的端口绑定也要保证本机可访问。
第一次使用
这一部分官方文档写得比较少,我只写有据可查的内容:
- 打开你的访问地址,注册账号。注册有 IP 频率限制(见上表,默认 3 次/小时),同一个出口 IP 后面的多个用户共用额度,官方提醒要按实际情况调整。
- 官方 README 说明加好友靠“昵称 + 一串随机数字”,群组要邀请才能加入。
- 要对外开放之前,先决定是否关掉访客登录、公开注册、用户创建群组(上面表里有对应开关)。
- 官方还有一个可选的管理后台,见下一节。
注册之后具体的界面操作(建群、加面板、装插件)我没有在文档里找到图文步骤,这里不展开。
可选:管理后台
官方文档说明管理后台还在迭代,目前是早期试用版。做法是:
wget https://raw.githubusercontent.com/msgbyte/tailchat/master/docker/admin.yml在 docker-compose.env 里设置:
ADMIN_USER=tailchat
ADMIN_PASS=这里写一个独立的后台密码然后用多文件方式启动,注意顺序,admin.yml 要放在后面:
docker compose -f docker-compose.yml -f admin.yml up -d访问地址是在你的服务地址后面加 /admin/(末尾的斜杠不能漏)。官方还写明,后台会把管理员登录和写操作记录到 MongoDB 的 audit_logs 集合里,记录只增不改,需要自己去 MongoDB 里清理。另外,仓库里的 admin.yml 还额外定义了一个 /admin-next 路由,但官方部署文档没有介绍,我不展开。
备份
官方的 MongoDB 运维文档给了备份和恢复命令,其中 <IMAGE_NAME> 指的是 MongoDB 容器:
docker exec -i <IMAGE_NAME> mongodump -d tailchat --archive > ./backup.archive
docker exec -i <IMAGE_NAME> mongorestore -d tailchat --archive < ./backup.archive默认数据库名是 tailchat,可以通过 MONGO_URL 修改。官方建议定时备份。在 Compose 项目里,我会把容器名换成 docker compose exec -T mongo ...,这是我对官方命令的改写,原理一样。
要注意,上面只备份了数据库。聊天里上传的文件在 MinIO 的 storage 卷里,官方文档没有写这部分的备份方法,通用做法是备份整个卷,或者停机后打包卷的内容。
更新与卸载
更新:官方的做法和部署时拿镜像一样。
docker pull moonrailgun/tailchat
docker tag moonrailgun/tailchat tailchat
docker compose up -d如果你固定了版本号,就把两个 moonrailgun/tailchat 换成想要的标签,例如 moonrailgun/tailchat:1.11.18。也可以用 npx tailchat-cli docker update。更新前先备份(通用建议,不是官方要求),并看一眼 GitHub 的发布说明。
卸载(以下是通用的 Docker Compose 操作,不是 Tailchat 官方文档):
docker compose down # 停止并删除容器,数据卷保留
docker compose down -v # 连同卷一起删除,聊天数据和上传文件都会没有,慎用踩坑清单
SECRET默认是公开的tailchat。 官方环境变量表明确说默认值是公开的,会让任何人伪造用户令牌。部署前必须换成长随机字符串。API_URL要改成自己的地址。 仓库的docker-compose.env示例值是项目方演示站的域名;官方说它用于文件服务访问,不设置会导致发出去的图片无法显示。API_URL必须带http://或https://。 官方排障文档:开放平台服务(openapi)不断重启,报Issuer Identifier must be a valid web uri,就是这个原因。- MinIO 的默认账号密码是公开的。 官方 Compose 里
MINIO_ROOT_USER: tailchat、MINIO_ROOT_PASSWORD: com.msgbyte.tailchat,env 文件里MINIO_USER、MINIO_PASS与之对应。MinIO 没有映射端口,风险不大,但建议部署时就改掉,并保证两处一致(后一句是通用判断)。 - Traefik 的几项配置官方自己标了不要照搬。 Compose 里
--api.insecure=true带注释Don't do that in production!,forwardedHeaders.insecure带注释Not good,并且挂载了只读的/var/run/docker.sock(Traefik 读取容器标签需要)。API 面板已经绑在127.0.0.1:11001,不要改成对外开放。 - 反向代理缺了 WebSocket 头,会出现“能注册但进不去主界面”。 检查
Upgrade和Connection两行。 - 后端要只能经由代理访问。 官方在注册限流部分说明,限流和最后登录 IP 取自
X-Forwarded-For,再是X-Real-IP,再是连接来源;代理必须清理转发头,且后端只能从代理访问,否则客户端可以自己决定用于限流的 IP。这也是我把端口绑到127.0.0.1的原因。 - Docker 发布的端口会绕过 ufw 之类的防火墙。 这是通用的 Docker 行为,不是 Tailchat 的问题,所以示例里绑定了
127.0.0.1。 - 上传大小有两道关。
FILE_LIMIT默认只有 1MB;Nginx 的client_max_body_size默认值也是 1MB(后者是 Nginx 通用知识)。想传大文件,两处都要调。 - 用了
image: tailchat就别忘了docker tag。 文件里同时有build,如果本地没有叫tailchat的镜像,Compose 会去当前目录构建而不是拉取(这是我对 Compose 行为的推断)。官方的公共镜像做法就是先 pull 再 tag。 - 基础镜像有的没固定版本。 官方 Compose 里是
mongo:4、redis:alpine、minio/minio(不带标签),Traefik 固定在v3.7.8。我没有核对mongo:4的支持状态;以后想升级数据库主版本,先备份,再看对应数据库官方的升级说明。 - 更新环境变量后,客户端可能没变化。 官方说明部分配置有缓存,需要清理,办法见前文。
- 没有邮箱服务,找回密码和邮箱验证用不了。 官方提供了
tailchat smtp verify和tailchat smtp test两个命令辅助排查;SMTP_SENDER的格式不对会报502 Invalid paramenters。 - 默认开启了遥测。 官方变量表里有
DISABLE_TELEMETRY,说明是匿名上报给项目方用于改进。介意的话设为1或true。 - 管理后台还是早期版本。 官方原话是还在迭代,目前是早期试用版。后台密码单独设置,并建议在代理层限制
/admin/的访问来源(后半句是通用建议)。
出处
有想法或问题?去留言板留言 →