自动更新
为 01MVP Desktop 配置 Tauri updater、签名产物和更新端点
你将学到
- 自动更新需要哪三样东西才能跑起来
- 为什么模板默认没启用 updater
- 用
tauri signer generate生成签名密钥 - 配置 Tauri 让应用知道去哪检查更新
- 搭建一个返回正确格式的更新端点
- 在应用内调用检查更新并处理四种状态
自动更新需要什么
桌面自动更新不是前端按一个按钮就行。它需要三样东西配合:
- 签名密钥 — 你的构建产物(DMG、MSI、AppImage)需要被签名。客户端拿到更新后会用公钥验证,确保安装包没被篡改。
- 更新端点 — 一个可访问的 HTTP 地址,应用启动时会请求它,告诉客户端"有没有新版本、去哪下载"。
- 应用内配置 — Tauri 的 updater plugin、端点地址、公钥,以及前端的检查更新逻辑。
这三样缺一个,更新流程就走不通。
为什么模板没默认开
模板保留了 src/runtime/updater.ts 的入口,但没启用 Rust 端的 updater plugin。原因是:自动更新需要真实发布域名、签名密钥对、每个平台的安装包和版本策略。如果模板写个假 endpoint,应用启动时反而容易出错。
当前做法是:未配置时 checkForDesktopUpdate() 返回 unavailable,应用正常启动,不报错。
如果还没有稳定下载域名和 updater 私钥,先保留"检查更新不可用"的状态。不要用临时 URL 做生产更新源。
第一步:生成签名密钥
Tauri 用 Ed25519 密钥对签名更新包。运行官方命令生成:
pnpm exec tauri signer generate --write-keys命令会输出公钥和私钥。私钥保存在本地安全位置,公钥后面要写进 tauri.conf.json。
私钥只放在 CI secret 或本机安全位置。别把 updater 私钥提交到仓库。
第二步:配置 Tauri
在 src-tauri/tauri.conf.json 中配置 updater:
{
"bundle": {
"createUpdaterArtifacts": true
},
"plugins": {
"updater": {
"endpoints": [
"https://updates.example.com/{{target}}/{{arch}}/{{current_version}}"
],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWdu..."
}
}
}endpoints 数组里可以放多个地址做容灾。模板变量 {{target}}、{{arch}}、{{current_version}} 会被运行时替换。
同时确保这些文件也改了:
| 文件 | 改什么 |
|---|---|
src-tauri/Cargo.toml | 添加 tauri-plugin-updater 依赖 |
src-tauri/src/lib.rs | 注册 updater plugin(.plugin(tauri_plugin_updater::init())) |
src-tauri/capabilities/default.json | 开放 updater 权限 |
package.json 里的 @tauri-apps/plugin-updater 已经在模板里保留了,不需要额外安装。
第三步:搭建更新端点
端点可以是静态 JSON,也可以是服务端 API。推荐服务端 API,因为它能按平台、架构和版本返回不同结果。
端点至少要返回这些字段:
{
"version": "0.2.0",
"notes": "修复了窗口拖拽问题,新增系统托盘菜单",
"pub_date": "2026-06-07T12:00:00Z",
"platforms": {
"darwin-aarch64": {
"signature": "dW50cnVzdGVkIGNvbW1lbnQ...",
"url": "https://releases.example.com/app_0.2.0_aarch64.app.tar.gz"
},
"darwin-x86_64": {
"signature": "dW50cnVzdGVkIGNvbW1lbnQ...",
"url": "https://releases.example.com/app_0.2.0_x64.app.tar.gz"
},
"windows-x86_64": {
"signature": "dW50cnVzdGVkIGNvbW1lbnQ...",
"url": "https://releases.example.com/app_0.2.0_x64-setup.nsis.zip"
}
}
}安装包放 R2、S3、GitHub Releases 或对象存储都行。闭源产品用 Cloudflare Worker + R2 更容易控制访问、缓存和下载统计。
如果当前版本已是最新,端点返回 HTTP 204 或空 body 即可,Tauri 会识别为"无更新"。
第四步:启用 Rust plugin
在 src-tauri/src/lib.rs 的 Tauri builder 中注册 plugin:
.plugin(tauri_plugin_updater::Builder::new().build())然后在 src-tauri/capabilities/default.json 里开放权限。如果只需要检查更新:
["updater:allow-check"]等下载和安装流程准备好后,再开放完整权限:
["updater:allow-check", "updater:allow-download", "updater:allow-install"]第五步:应用内检查更新
模板入口在 products/01mvp/apps/desktop/src/runtime/updater.ts。启用 Rust updater plugin 后,checkForDesktopUpdate() 会返回以下状态之一:
| status | 含义 |
|---|---|
available | 有新版本,包含版本号和 release notes |
none | 当前版本已是最新 |
unavailable | 当前构建没有配置 updater |
failed | 网络错误或端点异常 |
先只做"检查更新"按钮就够了。自动下载、静默安装这些等发布流程稳定后再加。
验证
启用自动更新后,按这个顺序跑一遍:
- 打开应用,点"检查更新" — 当前是最新版本时应显示 up to date
- 部署一个新版本 — 确认端点返回正确版本号和 notes
- 再次检查更新 — 应该看到新版本
- 确认下载 URL 可访问,签名校验通过
- 从旧版本完成一次完整更新流程
- macOS、Windows、Linux 分别验证
- 关闭端点或断网测试 — 确认 UI 不崩溃
- 没配置 updater 的开发构建仍能正常启动
每次发布后,用旧版本真实安装包跑一遍"检查更新 -> 下载 -> 安装"。CI 可以负责构建、签名、上传和发布 manifest,但下面这些需要你提前准备好:
- updater 私钥放进 CI secret,不能进仓库
- 下载域名和对象存储已经可访问
- preview / production 的 endpoint 分开
常见问题
为什么不能直接用私有 GitHub Release
用户机器上的桌面应用不该内置 GitHub token。私有 Release 直接当 updater 源会有认证和泄漏风险。更稳的做法是后端服务决定是否允许下载,再把短期可访问的安装包地址返回给客户端。
dev 构建需要自动更新吗
通常不需要。dev 构建主要用于调试,自动更新应该在 preview 或 production 渠道里测试。
updater 权限要一次性全开吗
不需要。先只开放 updater:allow-check 做检查。等下载和安装流程准备好后,再开放完整权限。
下一步
- macOS 签名与权限 — 正式分发前需要搞清代码签名、Developer ID 和 notarization
想和其他创造者交流?
这篇文档有问题?