更新与回档
以系统服务方式安装的 pwikit 会定期检查 GitHub 上的新版本,并在更新时段内自动安装。更新失败时自动回档到原来的版本。也可以随时手动更新,或回到上一个版本。
本文介绍自动更新的时间安排、更新失败时发生什么、如何手动更新与回档,以及相关设置。安装服务见部署。
查看当前版本
pwikit version输出版本号、构建所用的提交、平台和内置 PostgreSQL 的版本。见命令行。
自动更新
更新如何进行
执行 pwikit service install 时会一并注册一个计划任务,由它负责检查和安装新版本;pwikit service uninstall 会一并移除该任务。服务处于停止状态时,计划任务不做任何事。
一次自动更新依次经过以下阶段:
- 检查。 每小时从 GitHub 获取一次最新版本的信息。发现新版本后,立即在管理后台提示,并向能进入管理后台的成员发送站内通知。
- 安排。 发现比当前版本新的版本后,立即在最近一个更新时段(默认为 03:00–05:00,按
time_zone设置的时区,未设置时按服务器时区)内随机挑一个时间安排更新。从这时起,管理后台显示预计的更新时间;更新前 10 分钟,网站顶部向访问者显示更新横幅。 - 准备。 到达安排的时间后,下载新版本并校验 sha256,再用新版本检查本实例的数据库。任何一步失败都会放弃本次更新,网站不受影响。
- 安装。 停止服务,按需建立回档点(见回档点),替换可执行文件,然后启动服务。停机期间,访问者看到“正在更新”页面。
- 确认。 等待新版本正常提供页面。15 分钟内未能正常提供页面时,自动回档(见更新失败时)。
设置了 min_age 时,版本发布满这么久之后才会安排。错过安排的时间(例如机器处于休眠状态)时,更新顺延到下一个更新时段。
time_zone 填写时区数据库中的名称,如 Asia/Shanghai、Asia/Tokyo,不接受 UTC+9 这种写法。需要固定时差时可写 Etc/GMT-9,注意正负号相反,它表示 UTC+9。
不会自动安装的版本
以下情况下,新版本不会自动安装,只在管理后台提示:
| 情况 | 处理方式 |
|---|---|
| 版本会将内置 PostgreSQL 升级到新的主版本 | 执行 pwikit update 手动更新,见内置 PostgreSQL 的主版本 |
| 该版本曾经更新失败并已回档 | 修复原因后执行 pwikit update 手动重试 |
| 通过“跳过此版本”跳过了该版本 | 执行 pwikit update 手动安装 |
| 自动更新已推迟 | 推迟结束后的下一个更新时段重新安排 |
设置了 min_age,而版本发布未满这么久 | 发布满 min_age 后,在下一个更新时段安排 |
通过 pwikit update -to 或 pwikit update rollback 固定了版本 | 执行 pwikit update unpin 解除固定 |
| 自动更新已关闭 | 执行 pwikit update 手动更新 |
| 当前程序不是正式版本(自行构建且未指定版本号) | 不检查也不安装 |
| pwikit 运行在容器中 | 拉取新的镜像,见在容器中运行 |
除容器与非正式版本外,超级管理员也可以在管理后台选择立即更新以安装这些版本,见立即更新。
更新横幅与后台提醒
能进入管理后台的成员会在管理后台顶部看到新版本、更新计划、更新结果与回档的提醒,并在定时检查首次发现某个新版本时收到一条站内通知。超级管理员可以在提醒中推迟、跳过或立即更新,并能看到更新失败的原因。
自动更新开始前 10 分钟,本实例所有站点的页面顶部向所有访问者显示更新横幅。设置 public_banner = false 后,仅在管理后台提示。
立即更新
发现新版本后,超级管理员可以在管理后台的新版本提示中选择立即更新。更新安排在 10 分钟后,同样显示更新横幅,之后的步骤与自动更新相同。
立即更新不受更新时段、发布时间、跳过、推迟与版本固定的限制,自动更新关闭时也可以使用,并会安装会升级内置 PostgreSQL 主版本的版本。开始之前可以通过推迟取消。需要立即开始时,请使用手动更新。
推迟与跳过
在管理后台或命令行中操作:
pwikit update postpone
pwikit update skip| 操作 | 效果 |
|---|---|
| 推迟 | 取消当前的更新计划,24 小时内不再自动更新。之后重新安排到下一个更新时段,即通常顺延一晚 |
| 跳过 | 取消当前的更新计划,该版本不再自动安装。更新的版本发布后照常自动更新 |
关闭自动更新
在 pwikit.toml 中:
[update]
auto = false关闭后仍然每小时检查新版本,并在管理后台提示。设置 check = false 则完全不检查。修改后请重启服务。全部设置见配置。
手动更新
安装最新版本
在 Linux 与 macOS 上:
sudo pwikit update在 Windows 上,请在以管理员身份运行的终端中执行 pwikit update。
手动更新立即开始,不显示更新横幅,其余步骤与自动更新相同,失败时同样自动回档。手动更新不受更新时段、发布时间和“跳过”的限制,也会安装会升级内置 PostgreSQL 主版本的版本。
无论自动还是手动,更新都不会重新注册系统服务,也不会修改服务的启动参数:服务指向的可执行文件被原地替换,注册信息保持不变。
pwikit update check 只查询最新版本,不做任何更改。
安装指定版本
sudo pwikit update -to v1.0.1指定的版本比当前版本旧时,安装后固定在该版本,自动更新不会再把它升上去。执行以下命令解除固定:
pwikit update unpin能否安装较旧的版本取决于数据库,见旧版本与数据库。
未以系统服务方式运行的实例
这类实例不会自动更新。请先停止 pwikit serve,然后执行 pwikit update。pwikit 替换可执行文件并建立回档点后,请重新启动 pwikit serve。pwikit serve 正在运行时,pwikit update 会拒绝执行。
回档
更新失败时
新版本在 15 分钟内未能正常提供页面时,pwikit 会:
- 停止新版本,显示“正在更新”页面;
- 放回原来的可执行文件,并按回档点放回数据;
- 启动原来的版本,确认其正常提供页面;
- 将该版本记为失败,不再自动安装;
- 在管理后台显示回档提醒,并在已配置邮件服务器时,向所有设置了邮箱地址的超级管理员发送邮件,说明失败原因。
整个过程记录在数据目录的 logs/update.log 中。新版本在确认前不对外提供服务,因此自动回档不会丢失任何数据。
在停止服务、放入新版本之前的步骤失败(例如下载失败或磁盘空间不足)时,原来的版本保持运行或重新启动,数据不做任何改动,自动更新的计划保留,之后继续重试。
手动回档
更新完成后 7 天内,可以回到更新前的版本:
sudo pwikit update rollback回档点包含数据库时,pwikit 会先要求确认。
注意 回档点包含数据库时,回档会丢失更新之后产生的全部内容,包括新页面、编辑、评分与帖子。仅在新版本无法使用时回档。
指定 -yes 跳过确认。回档后,自动更新固定在原来的版本,直到执行 pwikit update unpin。
回档点
每次更新都在数据目录的 update/rollback/ 中建立回档点,保留 7 天:
| 更新的内容 | 回档点 | 回档时 |
|---|---|---|
| 没有数据库变更,或仅有兼容旧版本的变更 | 原来的可执行文件 | 仅放回可执行文件,数据保持不变 |
| 含有旧版本无法运行的数据库变更,使用内置 PostgreSQL | 原来的可执行文件与 pgdata/ 的完整副本 | 放回可执行文件与 pgdata/ |
| 含有旧版本无法运行的数据库变更,使用自有 PostgreSQL | 原来的可执行文件与数据库的备份 | 放回可执行文件并恢复数据库 |
| 内置 PostgreSQL 升级到新的主版本 | 原来的可执行文件与原来的 pgdata/ | 放回可执行文件与原来的 pgdata/ |
复制 pgdata/ 需要与数据库大小相当的可用磁盘空间。空间不足时放弃本次更新,并记录原因。
查看更新状态
pwikit update status 显示当前版本、上次检查的结果、更新计划、上次更新与可用的回档点。未安排更新时,说明原因。见命令行。
内置 PostgreSQL 的主版本
PostgreSQL 的一个主版本无法直接读取另一个主版本写入的数据。某个 pwikit 版本将内置 PostgreSQL 升级到新的主版本时,该版本不会自动安装。执行 pwikit update 手动更新时,pwikit 会自动完成:
- 在服务运行时备份数据库;
- 停止服务,将原来的
pgdata/移入回档点; - 放入新版本,由新版本的 PostgreSQL 创建新的
pgdata/并恢复备份; - 启动服务并确认。
失败时放回原来的 pgdata/ 与可执行文件。所需时间取决于数据库大小。
旧版本与数据库
新版本可能修改数据库结构。每项修改都标明是否兼容旧版本:
兼容的修改:旧版本可以继续在修改后的数据库上运行。回到旧版本不需要恢复数据。
不兼容的修改:旧版本拒绝在修改后的数据库上启动,并报错:
textpwikit: the database was upgraded by pwikit v1.1.0, which applied 0011_example.sql; this pwikit (v1.0.0) cannot run on that schema. Run pwikit v1.1.0 or a newer release, or restore a backup taken before the upgrade此时请运行报错中给出的版本,或恢复升级之前的备份。7 天内也可以使用
pwikit update rollback。
pwikit migrate status 将较新版本应用的修改列为 newer(兼容)或 newer-breaking(不兼容)。见命令行。
下载源与镜像
pwikit 从 GitHub 下载新版本,需要访问 github.com 与 objects.githubusercontent.com。服务器无法访问 GitHub 时,可以指定镜像。指定后,pwikit 每个文件都先从镜像下载;镜像出错、返回的文件校验不通过,或 1 分钟内没有收到任何数据时,改从 GitHub 下载:
[update]
mirror = "https://wikit.unitreaty.org/projwikit/update"也可以用命令写入,无需手动编辑文件。不带地址时显示当前镜像,地址写空字符串时清除:
pwikit update mirror https://wikit.unitreaty.org/projwikit/update
pwikit update mirror
pwikit update mirror ""修改后请重启服务。从镜像安装的实例已自动写入。
手动操作时也可以临时指定:
sudo pwikit update -mirror https://wikit.unitreaty.org/projwikit/update
pwikit update check -mirror https://wikit.unitreaty.org/projwikit/updatehttps://wikit.unitreaty.org/projwikit/update 是 ProjectWikit 维护者提供的镜像,转发 GitHub 上的发布文件,供中国大陆等无法稳定访问 GitHub 的服务器使用。
注意 ProjectWikit 的发布不做签名。pwikit 只校验文件与发布清单中的 sha256 是否一致,而清单本身也从镜像下载。配置镜像后,自动更新会安装该镜像提供的程序。请只使用您信任的镜像。
网络访问
检查更新会定期访问 GitHub,配置了镜像时改为访问镜像、镜像失败时才访问 GitHub,对方因此能看到服务器的 IP 地址。设置 check = false 后,pwikit 不再主动访问这些地址,也不再提示新版本。
在容器中运行
在容器中运行的 pwikit 不会自动更新,也不注册计划任务。请拉取新的镜像并重新创建容器:
docker compose pull
docker compose up -d见部署。
相关设置
更新相关的设置如下,另见配置。环境变量不会传递给系统服务与计划任务;以系统服务方式运行时,请使用 pwikit.toml,或在安装服务时将参数写在 -- 之后。
pwikit.toml [update] | 命令行参数 | 环境变量 | 默认值 | 含义 |
|---|---|---|---|---|
auto | -update-auto | PWIKIT_UPDATE_AUTO | true | 自动安装新版本 |
public_banner | -update-public-banner | PWIKIT_UPDATE_PUBLIC_BANNER | true | 向所有访问者显示更新横幅 |
check | -update-check | PWIKIT_UPDATE_CHECK | true | 检查新版本 |
window | -update-window | PWIKIT_UPDATE_WINDOW | 03:00-05:00 | 安装新版本的时段,按 time_zone 计算,可跨越午夜,如 23:00-01:00,至少 11 分钟 |
time_zone | -update-time-zone | PWIKIT_UPDATE_TIME_ZONE | 空 | window 所用的时区。留空时使用服务器的时区,设置后覆盖它。填写时区数据库中的名称,如 Asia/Shanghai、Asia/Tokyo;不接受 UTC+9 这种写法。需要固定时差时可写 Etc/GMT-9,注意正负号相反,它表示 UTC+9 |
min_age | -update-min-age | PWIKIT_UPDATE_MIN_AGE | 0s | 版本发布满这么久才会自动安装,如 24h、48h;为 0s 时发现后即安排到最近的更新时段 |
mirror | -update-mirror | PWIKIT_UPDATE_MIRROR | 空 | GitHub 无法访问时使用的镜像 |
命令行参数属于 pwikit serve。以系统服务方式运行时,请在安装服务时写在 -- 之后,例如:
sudo ./pwikit service install -- -update-window 02:00-04:00