news 2026/9/14 1:54:24

Wekan 在 AWS 上的部署与扩容实战:从单机小团队到数千用户生产环境

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Wekan 在 AWS 上的部署与扩容实战:从单机小团队到数千用户生产环境

Wekan 在 AWS 上的部署与扩容实战:从单机小团队到数千用户生产环境

【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan

本文是一份面向生产环境的 Wekan 部署与扩容指南,内容以 docs/Platforms/Propietary/Cloud/AWS/README.md 为骨架,覆盖两大典型场景:在 AWS 上承载数千用户的高可用集群,以及单台 EC2 + Docker 的多租户小团队部署。读完本文,你将掌握 Wekan 的实例规格选型、MongoDB 副本集与 OPLOG 连接串配置、nginx 反向代理 + Let's Encrypt SSL 的完整落地步骤、多客户路径隔离、AWS SES 邮件集成、Docker 数据备份恢复与版本升级的完整操作流程,并了解这些做法在 Wekan 源码与仓库配置文件中的依据。

Wekan 在 AWS 上的两种部署形态

Wekan 是基于 Meteor 构建的开源看板应用,其部署方式直接受 Meteor 架构约束:浏览器与服务器通过 DDP/SockJS 保持实时连接,服务器需要持续监听数据库的变更流。在 AWS 上部署 Wekan,可以根据团队规模和预算选择两种路径:

  • 多实例生产集群:面向数千用户,使用 ECS 集群运行多个 Wekan 应用容器,搭配 MongoDB 副本集,并通过MONGO_OPLOG_URL开启 OPLOG 实时推送。
  • 单服务器小团队部署:一台 Ubuntu EC2 + Docker Compose 即可承载,通过 nginx 反代和路径前缀(/customer1/customer2)在同一台机器上服务多个客户。

两条路径共享同一套镜像仓库与配置体系,区别主要在于实例数量和数据库拓扑。

面向数千用户的生产集群配置

推荐的实例规格

官方在生产环境验证过的方案(详见 AWS README)如下:

  • Node 层(ECS Cluster):3~4 台m4.large,每台承载一个 Wekan 应用实例。
  • MongoDB 层:3 台r4.large,组成一个副本集(Replica Set),其中 1 台 Primary 负责读写,另外 2 台为副本(Replica)。

文档明确指出,这一组合“可以非常稳定地支撑数千用户”(This setup runs very well for thousands of users)。副本集的意义不仅在于高可用:只有启用了副本集,MongoDB 才会产生oplog,而 oplog 正是 Meteor 实时数据推送(LiveData)的核心数据源。

关键:多实例必须设置 MONGO_OPLOG_URL

AWS 文档中引用了一个真实的生产事故修复案例:多实例部署时未设置MONGO_OPLOG_URL,导致 CPU 持续高占用。其原理是——Meteor 在未配置 OPLOG 时,会退化为“拉取并对比”(pull-and-diff)的数据同步方式,即定期把整个数据集拉到本地做 diff;而配置 OPLOG 后,Meteor 会订阅 MongoDB 的 oplog,由数据库主动推送变更事件,服务器只需增量应用即可。

官方在 docker-compose-mongodb-v7.yml 中正是同时给出了这两项配置(见第 357、408 行):

- MONGO_URL=mongodb://wekandb:27017/wekan?replicaSet=rs0 - MONGO_OPLOG_URL=mongodb://wekandb:27017/local?replicaSet=rs0

MONGO_OPLOG_URL指向的是 MongoDB 副本集的local 数据库(oplog 存储在 local 库中),因此连接串中的数据库名固定为local。在 AWS 文档给出的带认证示例中,格式为:

MONGO_OPLOG_URL=mongodb://<username>:<password>@<mongoDbURL>/local?authSource=admin&replicaSet=rsWekan

参数说明:

参数含义
<username>:<password>MongoDB 认证用户与密码
<mongoDbURL>MongoDB 主机地址(可带端口)
/local固定指向 local 数据库(oplog 所在库)
authSource=admin认证库为 admin
replicaSet=rsWekan副本集名称,必须与 MongoDB 实际副本集名一致

文档记录的真实效果:为所有 Wekan 实例设置MONGO_OPLOG_URL后,CPU 平均占用率降至10% 以下,仅在大规模操作时偶有尖峰。这一优化同样适用于任何基于 Meteor 的多实例应用。

进一步提升可扩展性

如果集群规模继续增长,AWS 文档建议引入Redis Oplog 支持:通过 redis-oplog 将 Meteor 的 OPLOG 事件订阅外移到 Redis,可显著降低对 MongoDB oplog 的直接压力。在 AWS 上可直接使用ElastiCache(Redis)作为承载。这是文档明确推荐的下一步扩容手段,适合用户量持续增长后的场景。

副本集与实时性的源码佐证

从当前仓库源码可以印证副本集对 Wekan 的重要性。在 attachmentStorageSettings.js 中,管理员执行附件存储压缩(compact)时,代码会先通过replSetGetStatus查询副本集状态,若存在 Secondary 节点,则先压紧凑 Secondary、再压缩 Primary,以保证 Primary 在压缩期间保持可用:

const rsStatus = await db.admin().command({ replSetGetStatus: 1 }); const secondaries = (rsStatus.members || []).filter(m => m.state === 2);

这段代码直接依赖 MongoDB 副本集拓扑,说明 Wekan 的运维模型(备份、压缩、滚动维护)都以副本集为前提,也解释了为什么生产集群文档要求使用 3 节点副本集而不是单实例 MongoDB。另外,默认的 docker-compose.yml(FerretDB 方案)会显式设置METEOR_REACTIVITY_ORDER=polling,改用轮询模式弥补 FerretDB 无 oplog 的不足;而 docker-compose-mongodb-v7.yml 中的 MongoDB 7 容器则会自动执行rs.initiate()初始化副本集并等待 Primary 选举成功,为实时推送(change-stream/oplog)提供基础。

面向企业的进一步建议

文档还给出了一条企业级建议:如果 WKAN 被企业大规模采用,与其自行维护分支,不如参与上游 Wekan 开发(将特性贡献回上游),并借助商业支持;Wekan 团队本身拥有高性能裸金属服务器用于高负载测试。对普通用户而言,理解这一点即可——大规模部署时,官方更推荐走上游主线而非长期 fork。

单服务器多租户安装(小团队方案)

AWS 文档用 16 个步骤完整描述了单台 EC2 上部署 Wekan 并为多个客户服务的流程。下面按阶段整理并补充关键细节。

阶段一:AWS 网络与实例准备

  1. 创建安全组:新建安全组(例如名为wekan),对所有人开放入站端口80 和 443;SSH 访问只对你的个人 IP 开放,CIDR 写法如123.123.123.123/32(/32 表示仅这一个 IP)。
  2. 启动 EC2 实例:使用Ubuntu 17.10 64 位(或更新的 Ubuntu LTS)镜像,至少2 GB 内存、30 GB 磁盘。文档提醒:随着客户增加,磁盘需求会上升,建议预留余量。实例创建时添加你的 SSH 公钥。
  3. 绑定弹性 IP(Elastic IP):为实例分配一个 Elastic IP。好处是:IP 长期不变;日后需要升级硬件时,可对实例做快照,用更大内存的实例类型启动新实例,再把 Elastic IP 指过去,即可最小化停机时间完成迁移(建议选择无活跃数据变更的时间段操作)。
  4. 配置 DNS:在 Route 53、Namecheap 或你的域名控制面板,把subdomain.yourdomain.comA 记录指向 Elastic IP。DNS 全球生效最长需要 24 小时。

阶段二:系统初始化与基础组件

  1. SSH 登录服务器
ssh -i pubkey.pem ubuntu@server-ip-address # 部分镜像为 root 用户,则使用 root@server-ip-address
  1. 更新系统全部软件包
sudo apt update sudo apt -y dist-upgrade reboot
  1. 安装 Docker CE 与 docker-compose:从 docker.com 官方源安装,安装后把ubuntu用户加入docker组(post-install 步骤)。
  2. 安装 nginx 反向代理
sudo apt install nginx # 或安装带额外模块的版本:sudo apt install nginx-full sudo systemctl start nginx sudo systemctl enable nginx

nginx 的完整站点配置模板(含 WebSocket 升级、SSL 与反向代理)见 docs/Platforms/Webserver/Nginx.md,我们将在下一节详细展开。配置完成后校验并生效:

sudo nginx -t # 校验配置语法 sudo systemctl reload nginx
  1. 安装 certbot:从 certbot.eff.org 获取 Let's Encrypt SSL 证书,并把 HTTP 流量重定向到 HTTPS。

阶段三:多租户路径规划

  1. 不同客户使用不同路径前缀:在同一个 nginx virtualhost 子域配置文件中,为每个客户写一个独立的location /customer1location /customer2块,各自反向代理到本机不同的 localhost 端口上的 Wekan 容器。这样一台服务器即可服务多个客户。
  2. 获取最新版本与配置说明:查看 Wekan 官方 release 页获取最新版本号;docker-compose.yml中所有环境变量的含义都在官方 wekan-mongodb 仓库的 compose 文件中有注释说明(当前仓库的 docker-compose.yml 与 docker-compose-mongodb-v7.yml 同样对每个变量做了详尽注释)。核心设置示例:
ROOT_URL=https://sub.yourdomain.com/customer1 ports: - 8080:80 # 宿主机 localhost:8080 映射到容器内 80 端口

镜像必须使用明确的版本标签,不要用latest

image: quay.io/wekan/wekan:v0.70

文档特别强调:只使用 release 版本标签,因为latest标签偶尔可能是损坏的构建。

关于ROOT_URL的重要提示(可参考 server/00checkStartup.js 的启动校验):Wekan 通过邮件发送的邀请链接、密码重置链接、以及地址验证都由ROOT_URL拼装而成。如果ROOT_URL设置错误,发出的链接会指向错误地址。在子路径部署时,ROOT_URL必须包含路径(如https://sub.yourdomain.com/customer1)。

阶段四:AWS SES 邮件集成

  1. 配置 AWS SES:在 AWS SES 控制台添加发件邮箱地址与域名,并验证SPFDKIM(若域名托管在 Route 53,可用其 wizard 一键完成)。然后在 SES 创建新的 SMTP 凭据,填入 docker-compose.yml 的 SMTP 设置。

AWS SES 的 SMTP 端点、SPF TXT 记录以及排错细节见 docs/Features/Email/Troubleshooting-Mail.md。其中对 AWS SES 的典型配置是(注意:SES 凭据无需 urlencode 特殊字符):

- MAIL_FROM=Wekan Boards <boards@example.com> - MAIL_URL='smtp://username:password@email-smtp.eu-west-1.amazonaws.com:587?tls={ciphers:"SSLv3"}&secureConnection=false'

SPF 记录示例(123.123.123.123换成你的服务器 IP):

@ TXT "v=spf1 ip4:123.123.123.123 include:amazonses.com ~all"

阶段五:启动与多租户容器管理

  1. 启动 Wekan 与数据库容器
docker-compose up -d

请求链路为:nginx SSL 443 端口 → 代理到 localhost:8080(或其他端口)→ wekan-app 容器内 80 端口。 14.每个客户独立目录:为不同客户准备不同的 docker-compose.yml,放在以客户命名的目录中(如wekan-customer1/)。必要时把容器从默认的wekan-app重命名为wekan-customer1,并相应调整 Docker 内部网络名称,避免冲突。 15.备份、恢复与数据迁移:详见 docs/Platforms/FOSS/Container/Docker/Export-Docker-Mongo-Data.md(下文有精简版流程)。 16.首次登录与管理员配置:打开https://subdomain.yourdomain.com/customer1/sign-up注册,在https://subdomain.yourdomain.com/customer1/sign-in登录。第一个注册的用户自动成为管理员。登录后点击右上角用户名进入 Admin Panel,把注册设置改为“仅邀请”(invite only),避免陌生人注册。

nginx 反向代理与 SSL 配置详解

AWS 安装步骤第 8、9 步提到的 nginx 配置,其完整模板在 docs/Platforms/Webserver/Nginx.md。由于 Wekan(Meteor)使用 WebSocket(SockJS)进行实时通信,nginx 配置中 WebSocket 升级是否正确,直接决定看板能否实时刷新

站点配置(/etc/nginx/conf.d/example.com.conf 或 sites-available 下)

# 这段 map 必须放在 http { } 上下文中,不能放在 server/location 内 map $http_upgrade $connection_upgrade { default upgrade; '' close; } # HTTP:非 SSL 流量重定向到 HTTPS server { listen 80; listen [::]:80 ipv6only=on; server_name example.com; location / { rewrite ^ https://example.com$request_uri? permanent; } } # HTTPS server server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; location / { proxy_pass http://127.0.0.1:3001; # 指向 Wekan 容器的宿主端口 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; # 允许 WebSocket 升级 proxy_set_header Connection $connection_upgrade; # 由 map 决定 upgrade/close proxy_set_header X-Forwarded-For $remote_addr; # 保留客户端真实 IP } }

关键点(Nginx.md 中有完整排错章节):

  • map必须在 http 上下文中,放在 server/location 内不生效;
  • Connection头必须使用$connection_upgrade变量,不能硬编码"""upgrade",否则 SockJS 的/sockjs/.../websocket请求无法完成升级,浏览器控制台会报WebSocket connection to 'wss://HOST/sockjs/.../websocket' failed,Wekan 会退化为慢速长轮询;
  • proxy_http_version 1.1;是必需的(WebSocket 依赖 HTTP/1.1,默认 1.0 无法升级);
  • 若 Wekan 前面有多级代理/负载均衡,每一跳都需要这三行。

常见问题

  • 看到 “Welcome to Nginx” 默认页:多半是/etc/nginx/conf.d//etc/nginx/sites-available/下存在自动生成的default文件抢占了默认 server,删除它们即可(参考 Nginx.md 中引用的真实案例)。
  • CentOS 7 上 nginx 连不上容器:执行setsebool -P httpd_can_network_connect 1允许 Web 服务连接容器,不要关闭 SELinux
  • 页面日期格式异常:需要在 Content-Security-Policy 中追加'unsafe-eval'
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'";
  • 附件上传被拒(413 Request Entity Too Large):在http { }中调大限制:
client_max_body_size 100M;
  • 启用站点:把配置文件软链接到sites-enabled,然后sudo nginx -t校验、sudo systemctl reload nginx生效。完整流程见 Nginx.md。

Docker 数据备份、恢复与跨容器迁移

AWS 部署步骤 15 引用的 Export-Docker-Mongo-Data.md 提供了完整的 MongoDB 备份恢复方案。核心要点:

  • 恢复前必须先停 Wekan 应用容器docker stop wekan-app),否则导入数据可能与运行中的应用冲突;
  • 确认MONGO_URL中的数据库名正确(如wekanadmin),否则恢复后数据库可能是空的;
  • Docker 数据默认存放在宿主机/var/lib/docker,直接操作该目录风险高、难以恢复,用 mongodump 文件恢复要容易得多,因此强烈建议以 mongodump 为备份手段。

手动备份/恢复流程

# 1) 进入 MongoDB 容器 docker exec -it wekan-db bash # 2) 备份到容器内 /dump 目录(只备份 wekan 数据库,不含 local) mongodump -o /dump/ # 3) 退出容器,把备份拷到宿主机当前目录 exit docker cp wekan-db:/dump . # 4) 恢复(先把 dump 拷回容器,再 mongorestore) docker cp dump wekan-db:/data/ docker exec -it wekan-db bash cd /data mongorestore --drop --db wekan /data/dump/wekan/ exit

若恢复时报“索引已存在”类错误,可在 mongorestore 中加--noIndexRestore参数跳过索引重建。

自动化备份脚本(删除 7 天前旧备份)

#!/bin/bash DATE=$(date +%Y-%m-%d-%H-%M) SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" cd $SCRIPTPATH mkdir -p backups/$DATE docker ps -a | grep 'wekan-db' &> /dev/null if [ $? = 0 ]; then docker exec -t wekan-db bash -c "rm -fr /dump ; mkdir /dump ; mongodump -o /dump/" docker cp wekan-db:/dump $SCRIPTPATH/backups/$DATE tar -zc -f backups/$DATE.tgz -C $SCRIPTPATH/backups/$DATE/dump wekan if [ -f backups/$DATE.tgz ]; then rm -fr backups/$DATE find $SCRIPTPATH/backups/ -name "*.tgz" -mtime +7 -delete fi else echo "wekan-db container is not running" exit 1 fi

注:以上命令与脚本以传统 MongoDB 容器(wekan-db)为例。当前仓库默认的 docker-compose.yml 使用 FerretDB + SQLite 后端,备份对象与命令不同;使用 docker-compose-mongodb-v7.yml 的 MongoDB 7 副本集方案时,则与上述 mongodump 流程一致。

升级 Wekan 到新版本

AWS 文档给出了一套安全升级流程,核心原则是先备份、再换镜像标签、最后验证

# 1) 进入客户目录并创建备份目录 cd wekan-customer1 mkdir backup-2018-02-03 cd backup-2018-02-03 # 2) 按上一节方法在备份目录中完成数据库备份 # 3) 回到客户目录,编辑 docker-compose.yml 更新版本标签 # image: quay.io/wekan/wekan:v0.70 → image: quay.io/wekan/wekan:v0.71 # 4) 重启 Wekan docker-compose stop docker-compose start
  1. 登录 Wekan,在 Admin Panel 确认版本号已更新。

如果版本未更新,可用以下 Docker 命令排查:

docker ps # 查看运行中的容器 docker images # 查看本机已安装的镜像 docker stop wekan-app # 停止旧容器(或用 CONTAINER-ID) docker rm wekan-app # 删除旧容器 docker rmi quay.io/wekan/wekan:v0.70 # 删除旧镜像 docker-compose up -d # 用新配置重新创建并启动容器

注意:升级后若直接docker-compose start不生效(容器仍引用旧镜像),通常需要docker-compose up -d重建容器。

部署清单速查

事项关键操作/配置依据文档
多实例集群3~4× m4.large (Node) + 3× r4.large (Mongo 副本集)AWS README
实时数据推送必须设置MONGO_OPLOG_URL=mongodb://.../local?...&replicaSet=...同上;docker-compose-mongodb-v7.yml
进一步扩容引入 redis-oplog,AWS 上用 ElastiCacheAWS README
安全组开放 80/443,SSH 仅限本机 IP(/32)同上
多租户nginxlocation /customerN→ 各自 localhost 端口;每客户独立 compose 目录同上
镜像版本只用版本标签,不用latest同上;docker-compose.yml 注释
邮件AWS SES 验证 SPF/DKIM,新建 SMTP 凭据Troubleshooting-Mail.md
WebSocket 反代map $http_upgrade+Connection $connection_upgrade+proxy_http_version 1.1Nginx.md
备份恢复停应用 → mongodump → 拷出/拷入 → mongorestoreExport-Docker-Mongo-Data.md
升级备份 → 换镜像标签 → stop/start → Admin Panel 验证AWS README

结语

无论是数千用户的 ECS + MongoDB 副本集集群,还是单机多租户的 nginx + Docker 方案,Wekan 在 AWS 上的生产部署都遵循同一条主线:用 MongoDB 副本集 +MONGO_OPLOG_URL保证 Meteor 实时推送的规模上限,用 nginx 正确处理 WebSocket 升级保证前端实时体验,用版本标签 + 备份先行保证升级安全。本文引用的配置模板与脚本均来自仓库 docs/Platforms/Propietary/Cloud/AWS/README.md 及其关联的 Nginx、邮件、备份文档,可直接作为运维手册使用;当前仓库中的 docker-compose.yml 与 docker-compose-mongodb-v7.yml 则是上述所有环境变量的权威注释来源。

【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 1:53:34

从汽车电子到AI:电源管理器件选型实战与底层基石

干硬件这行时间长了&#xff0c;你会发现一个很有意思的现象&#xff1a;每次项目复盘&#xff0c;最终定位到的问题往往不在SoC&#xff0c;不在MCU&#xff0c;而是在那些最初选型时只花了五分钟的元器件上。电源管理链路更是重灾区。这几年从汽车电子项目做到AI相关的主板与…

作者头像 李华
网站建设 2026/9/14 1:53:07

智能高边驱动芯片:汽车电子保险丝的芯片化革命

1. 项目概述&#xff1a;当保险丝开始“思考”——汽车电子保护机制的代际跃迁“汽车里的保险丝&#xff0c;怎么变成芯片了&#xff1f;”——这句话最近在汽修厂、4S店技术群和新能源车主论坛里反复刷屏。它不是一句调侃&#xff0c;而是真实发生在你我每天驾驶的车辆底盘下、…

作者头像 李华
网站建设 2026/9/14 1:52:29

嵌入式语音频谱分析:从FFT原理到C语言DSP实现

简介&#xff1a;一套基于C语言的DSP FFT语音频谱分析示例工程&#xff0c;面向数字信号处理初学者及嵌入式开发者&#xff0c;旨在帮助理解快速傅里叶变换原理&#xff0c;并实践语音信号的频域分析方法。压缩包内含59个文件&#xff0c;体积约95KB&#xff0c;主要包含C源码、…

作者头像 李华
网站建设 2026/9/14 1:51:47

5 分钟把小爱音箱接入大模型:MiGPT 实操配置指南

5 分钟把小爱音箱接入大模型&#xff1a;MiGPT 实操配置指南 【免费下载链接】mi-gpt &#x1f3e0; 将小爱音箱接入 ChatGPT 和豆包&#xff0c;改造成你的专属语音助手。 项目地址: https://gitcode.com/GitHub_Trending/mi/mi-gpt "小爱同学&#xff0c;请讲个笑…

作者头像 李华
网站建设 2026/9/14 1:51:00

智能家居的本质是可生长的家庭操作系统

1. 智能家居不是“买一堆设备回家”&#xff0c;而是构建一套可生长的居家操作系统 “智能家居”这四个字&#xff0c;现在几乎贴满了所有家电卖场的展台、装修公司的方案册、甚至二手房中介的宣传单。但你有没有发现一个奇怪的现象&#xff1a;很多人花几万块买了智能灯、智能…

作者头像 李华
网站建设 2026/9/14 1:49:27

24GB显存也能跑物理世界视频生成:Cosmos安装到出片实战指南

24GB显存也能跑物理世界视频生成&#xff1a;Cosmos安装到出片实战指南 【免费下载链接】cosmos NVIDIA Cosmos is an open platform of world models, datasets, and tools that enables developers to build Physical AI for robots, autonomous vehicles, smart infrastruct…

作者头像 李华