Zulip 服务器自定义修改完全指南:基于 Git 分支的生产环境定制、升级与维护 Zulip 服务器自定义修改完全指南基于 Git 分支的生产环境定制、升级与维护【免费下载链接】zulipZulip server and web application. Open-source team chat that helps teams stay productive and focused.项目地址: https://gitcode.com/GitHub_Trending/zu/zulipZulip 是 100% 免费开源的团队协作软件官方不仅允许、而且鼓励用户基于自身需求对其进行修改。本篇技术指南以 Zulip 官方生产部署文档中关于修改 ZulipModify Zulip的核心内容为骨架完整讲解自托管服务器上的两种定制路径——维护自研分支与跟随上游main——并深入 upgrade-zulip-from-git 等脚本的源码实现帮助读者掌握一套安全、可维护、可长期跟随上游版本的 Zulip 定制工作流。读完本文你将能够确认服务器版本并创建基于指定版本的定制分支、通过 Git 分支将改动安装到生产服务器、在版本升级时用 rebase 平滑迁移改动、以及安全地应用来自main分支的修复。修改前必须确认的事实保持对官方版本与责任边界的认知官方文档开宗明义如果你修改了 Zulip 并向社区报告问题请负责任地说明这一事实。理想情况下应先在一个未修改的版本例如官方开发社区或 Zulip 云端中复现问题如果难以复现或你认为自己的改动与问题几乎无关也务必在问题报告中提及你的改动。这是与上游协作的基本礼仪也是后续所有操作的前提。另一个必须建立的基础认知是版本匹配。在服务器上执行任何修改前先确认运行中的 Zulip 版本查看/home/zulip/deployments/current/version.py中的ZULIP_VERSION。若将改动应用到错误版本上很可能导致升级失败甚至停机。仓库根目录的 version.py 展示了版本信息结构例如当前仓库为ZULIP_VERSION 12.0-devgit并附带LATEST_MAJOR_VERSION、LATEST_RELEASE_VERSION等字段以及ZULIP_MERGE_BASE当前代码相对上游公共分支的合并基点提交哈希——后者在排查定制分支与上游差异时非常有用。为什么不要直接编辑/home/zulip/deployments/current最直观的修改方式是在服务器上直接编辑/home/zulip/deployments/current下的文件然后重启服务。官方明确指出这种方式只适合临时测试对 Python 代码或 shell 脚本的小改动不推荐用于维护长期改动原因有四无法修改前端文件JavaScript、CSS 及其他前端文件不以可编辑形式包含在生产发布 tarball 中。官方给出的理由是包含可编辑前端源码会显著增大 tarball 体积而运行时根本用不到。升级即丢失下次升级 Zulip 服务器时改动会全部丢失。原因可以从部署机制理解——升级本质上是创建一个全新的部署目录见下文make_deploy_path旧目录中的直接改动不会被迁移。容易遗漏重启需要手动重启服务改动才会生效。无法追踪改动不受版本控制出错后难以调试。此外若采用 Docker 部署直接改文件甚至更危险容器每次从固定镜像启动重启容器后改动即消失详见 docs/production/docker.md。推荐的定制工作流Git 分支 upgrade-zulip-from-git官方推荐的是基于 GitHub 的 fork 工作流。其核心思路是所有改动都发生在你本地的 Git 仓库中通过upgrade-zulip-from-git脚本将指定 Git 引用分支/标签/提交构建并安装到生产服务器。这套工作流一举解决了直接编辑的全部四个问题改动会被正确编译并安装自动重启服务器且被 Git 追踪方便在未来的 Zulip 版本间维护。第一步在本地准备代码环境建议在桌面或笔记本上使用 Zulip 开发环境官方文档完整介绍了开发环境搭建它可以让你无需部署到生产就能极其方便地测试改动。如果改动很小、或能接受停机风险也可以不搭建开发环境——只需一台装有 Git 的机器即可。随后参照 Git 指南 完成 fork 与克隆克隆官方指南 详细说明了 fork 官方仓库、配置upstreamremote 的完整步骤。第二步基于正确版本创建分支cd zulip git checkout -b acme-branch 2.0.4其中2.0.4是服务器当前运行的版本按前文方式从version.py确认。必须基于服务器实际版本创建分支这是避免改动应用到错误版本导致失败与停机的最关键一步。第三步修改、提交并推送git commit -a # 用 git diff 核对改动是否符合预期 git diff 2.0.4 acme-branch # 推送到你的 GitHub fork git push origin acme-branchgit diff 2.0.4 acme-branch的作用是核对分支相对基线版本的全部差异这是每次安装或升级前都应该执行的自我检查。第四步在服务器上安装改动登录 Zulip 服务器配置并使用upgrade-zulip-from-git安装改动在/etc/zulip/zulip.conf的[deployment]段配置git_repo_url指向你的 fork见下文配置仓库地址以 root 身份执行upgrade-zulip-from-git acme-branch。upgrade-zulip-from-git源码级剖析upgrade-zulip-from-git分两层实现理解它们能帮你更从容地排查问题scripts/upgrade-zulip-from-git 是一个 bash 薄封装校验必须以 root 运行将真实逻辑转发给scripts/lib/upgrade-zulip-from-git并把全部输出追加到/var/log/zulip/upgrade.log便于事后调试失败时会以红色提示升级过程被设计为幂等的解决上方 traceback 所示问题后可直接重试。scripts/lib/upgrade-zulip-from-git 是 Python 实现的主流程关键机制包括机制说明本地 Git 镜像缓存使用/srv/zulip.gitLOCAL_GIT_CACHE_DIR作为裸仓库缓存首次使用时自动git init --bare并添加 origin配置读取通过 zulip_tools.py 的get_config读取/etc/zulip/zulip.conf中[deployment]段的git_repo_url默认值为上游官方仓库引用解析依次尝试将传入的refname解析为refs/tags/{refname}标签或refs/remotes/origin/{refname}远程分支工作树部署用git worktree add --detach将指定提交检出到新部署目录非 tag 引用还会额外checkout -b deployment-时间戳分支部署目录机制新部署目录由make_deploy_path()生成即/home/zulip/deployments/时间戳随后把/etc/zulip/settings.py符号链接到新部署的zproject/prod_settings.py并把新目录符号链接为deployments/next部署锁get_deployment_lock通过mkdir /home/zulip/deployments/lock保证同一时间只有一个部署在进行若锁超时未释放会提示手工rmdir清理对应 zulip_tools.py阶段二升级最终调用scripts/lib/upgrade-zulip-stage-2带--from-git标记完成依赖安装、静态资源构建与数据库迁移额外参数方面--remote-url可临时覆盖zulip.conf中配置的仓库地址--local-ref表示分支已直接推送到/srv/zulip.git无需再从远端拉取。这些选项的完整说明可见脚本中的 argparse 定义。配置仓库地址git_repo_url在/etc/zulip/zulip.conf中添加如下配置即可让upgrade-zulip-from-git从你的 fork 拉取代码与 升级文档 中从另一个仓库升级的配置方式一致[deployment] git_repo_url https://github.com/zulip/zulip.git将 URL 替换为你的 fork 地址后后续所有upgrade-zulip-from-git branch调用都会自动从该仓库获取引用。若需要自定义部署选项还可以通过[deployment]段的deploy_options传递额外参数由get_deploy_options解析见 zulip_tools.py。升级到未来版本用 rebase 维护你的分支当官方发布新版本时你的改动需要随之迁移。分两种情况改动已被官方合并、或不再需要直接按 常规升级流程 升级即可下载 tarball 后用upgrade-zulip安装。改动仍需保留用git rebase --onto把分支迁移到新版本上。示例假设分支基于 2.0.4要升级到 2.1.0cd zulip git fetch --tags upstream git checkout acme-branch git rebase --onto 2.1.0 2.0.4 # 解决可能出现的错误与合并冲突可参考 Zulip 的 Git 指南 # 用 git diff 核对改动是否符合预期 git diff 2.1.0 acme-branch git push origin acme-branchgit rebase --onto 2.1.0 2.0.4的含义是把acme-branch中自2.0.4以来的提交全部搬到2.1.0之上。rebase 过程中出现合并冲突是正常现象逐条解决即可。完成后再次用git diff核对然后照旧通过upgrade-zulip-from-git安装更新后的分支。一个重要的特殊场景如果你之前升级到了main分支那么官方发布的新的维护版本如2.1.x很可能老于你当前的安装此时应该再次升级到main而非降级到维护版本。Docker 部署下的差异如果使用官方 Docker 镜像参见 docs/production/docker.md上述流程有两点不同直接编辑文件更加不可靠——容器每次从固定镜像启动重启容器即丢失改动不再运行upgrade-zulip-from-git而是使用Docker 的升级工作流基于docker compose的compose-upgrading流程基于你修改后的 Zulip 版本重新构建容器镜像。应用来自main的改动官方社区的很多 bug 修复已合入main但尚未进入正式发布。如果你急需这些修复有两条路径。路径一应用小改动cherry-pick许多 bug 的修复小而简单。此时沿用前文的 Git 工作流只是把本地做修改换成摘取官方提交git fetch upstream git cherry-pick abcd1234其中abcd1234是目标改动的提交 ID。官方明确说明如果 cherry-pick 任意提交导致的问题并不影响main或官方发布版通常无法获得免费支持唯一的例外是官方主动请你应用某补丁以验证修复时社区会积极响应排障。另外如果某个小修复对你很重要可以尝试询问官方是否将其加入当前稳定发布分支如2.1.x稳定分支上的改动会被当作已发布内容一样对待并随下一个 bug 修复版本发布。路径二升级到main许多大型 Zulip 服务器如 chat.zulip.org 与 zulip.com会定期升级到main以获取最新特性。在这么做之前官方强烈建议先理解以下事实版本号逻辑在 Zulip 的版本编号方案中main永远新于最新维护版如3.1、2.1.6又老于下一个大版本如3.0、4.0。活跃度main处于非常活跃的开发中多数日子会合入数十个新改动相对最新发布版通常包含数以千计的变更全部会进入下一个大版本。平均而言main的总 bug 数往往更少因为每个大版本都会修复数百个 bug但也可能存在比发布版更严重的问题。稳定性承诺官方定期常常是每日将main部署到 chat.zulip.org 和 zulip.com因此main必须保持稳定多数回归只是轻微的 UX 问题且会被快速修复。社区支持态度社区非常乐于帮助排查从最新发布版升级到main出现的问题这是大版本发布前消除同类问题的最佳时机远胜过对其他定制改动的支持热情但官方不承诺无正式支持合同的用户的问题解决速度。不支持降级官方不支持从main降级到更早版本。如果服务器停机不可接受务必在升级前持有最新的备份。changelog 可用变更日志 中列出大版本以来的主要变更草稿其中Upgrade notes部分始终是最新的。安全修复同步官方发布安全或维护版本时其改动总会合并回main因此升级到main即可获得安全修复。可逆性main发布后你总能通过upgrade-zulip-from-git或发布 tarball 从main升级到下一个大版本不存在被困在 main的风险。从底层实现看升级到main与升级到普通分支并无本质区别——upgrade-zulip-from-git main只是把引用解析为refs/remotes/origin/main唯一额外动作是脚本会根据引用是否为 tag 来决定是否附加-t参数非 tag 分支会创建部署专用分支。风险主要来自上文列举的版本语义与数据库迁移。关于从main向旧版本回移植backport任意补丁官方也给出了需要小心的常见原因改动包含数据库迁移*/migrations/下的新文件——大多数新特性都如此而官方不支持乱序应用数据库迁移改动叠加在其他改动之上任何数百行规模的补丁几乎都会产生合并冲突需要额外工作量。这类改动虽然理论上可以回移植但没有官方支持合同的用户通常难以成功。将你的改动贡献回上游Zulip 包含数千个由志愿者贡献的改动。如果你的改动对其他组织也可能有用官方鼓励将其贡献回社区完整流程参见贡献指南。贡献的前提是遵守前文提到的责任边界报告问题时清晰说明自己运行的是定制版本并尽量先在未修改版本中复现。附升级失败时的恢复手段尽管不属于 modify.md 的核心步骤但维护定制分支必然涉及反复升级因此掌握回滚手段很有必要。根据升级文档升级脚本是幂等的解决问题后重试没有副作用最常见失败原因是网络问题以及内存较小的机器在执行tools/webpack构建前端资源时 OOM可先用./scripts/stop-server释放内存再升级。所有升级日志输出到/var/log/zulip/upgrade.log服务端内部错误日志在/var/log/zulip/errors.log。由于每次部署都在/home/zulip/deployments/下创建独立目录并通过current/last/next符号链接切换回滚只需运行/home/zulip/deployments/last/scripts/restart-server或指定历史时间戳目录的restart-server即可切回旧版本。这套新版本独立部署目录 符号链接切换的设计正是前文工作流能够安全反复尝试升级的底层保障——你的定制分支每次安装都会生成一个新部署旧部署始终保留随时可以回退。总结修改 Zulip 的正确姿势可以浓缩为三条原则不在生产目录直接编辑一切改动入 Git 分支分支严格基于服务器实际版本创建升级时用rebase --onto迁移服务器端统一通过upgrade-zulip-from-git安装。无论是维护长期定制的 fork还是临时应用来自main的修复这套工作流都能保证改动被正确编译安装、被版本控制追踪、并能在未来版本间平滑迁移。理解 scripts/lib/upgrade-zulip-from-git 与 zulip_tools.py 中的部署锁、工作树、符号链接机制能让你在排查升级问题时有的放矢。【免费下载链接】zulipZulip server and web application. Open-source team chat that helps teams stay productive and focused.项目地址: https://gitcode.com/GitHub_Trending/zu/zulip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考