vaultwarden的升级和部署修改为1.37版本

This commit is contained in:
2026-07-29 16:41:58 +08:00
parent 99e9ec1434
commit 1bfd657f99
6 changed files with 901 additions and 59 deletions
+112 -16
View File
@@ -16,7 +16,7 @@ Bitwarden 兼容的自托管密码管理器,轻量、安全、功能完整。
| 组件 | 版本 | 说明 |
|------|------|------|
| Vaultwarden | latest | Bitwarden 兼容服务端(Rust 实现) |
| Vaultwarden | 固定版本号 | Bitwarden 兼容服务端(Rust 实现),由 `upgrade.sh` 升级 |
| SQLite | 内置 | 轻量数据库,无需额外部署 |
| Nginx | 系统包 | 反向代理 + HTTPSBitwarden 客户端必须 HTTPS |
| Docker | 最新版 | 容器运行环境 |
@@ -35,6 +35,7 @@ vaultwarden/
├── docker-compose.yml # 容器编排
├── .env.example # 配置模板
├── deploy.sh # 一键部署脚本
├── upgrade.sh # 安全升级脚本(带备份、校验、自动回滚)
├── backup.sh # 备份脚本
├── uninstall.sh # 完全卸载脚本
├── nginx/
@@ -97,9 +98,12 @@ bash deploy.sh
cd /opt/vaultwarden
# 编辑 .env,将 SIGNUPS_ALLOWED 改为 false
vi .env
docker compose restart
docker compose up -d # 注意:不是 restart
```
> **不要用 `docker compose restart`**。环境变量是在容器**创建**时注入的,`restart` 只是重启
> 原容器、不会重建,改了 `.env` 也不会生效。必须用 `up -d` 让 compose 检测到配置变更并重建容器。
### 第五步:安装客户端
1. 下载 Bitwarden 客户端:https://bitwarden.com/download/
@@ -224,23 +228,65 @@ docker compose up -d
### 升级
使用 `upgrade.sh` 升级,**不要**手动 `docker compose pull && up -d`(见下方「为什么不要手动升级」)。
```bash
cd /opt/vaultwarden
# 1. 备份数据
bash backup.sh
# 2. 拉取新镜像
docker compose pull
# 3. 重启
docker compose up -d
# 4. 检查运行状态
docker compose ps
docker compose logs --tail 20
bash upgrade.sh --check # 先看看会发生什么,不做任何改动
bash upgrade.sh # 正式升级到 GitHub 最新 release
```
脚本执行流程:
| 步骤 | 动作 | 失败时 |
|------|------|--------|
| 1 | 预检:root、依赖命令、数据目录、磁盘空间 | 直接退出,未动服务 |
| 2 | 拉取新镜像 | 直接退出,**服务零影响**,可安全重试 |
| 3 | 把当前镜像打上 `pre-upgrade-<时间戳>` 标签作为回滚锚点 | — |
| 4 | 停止容器 | 自动拉起原服务 |
| 5 | WAL checkpoint + `integrity_check` + 冷备份整个数据目录 | 自动拉起原服务 |
| 6 | 切换镜像并 `--force-recreate` 重建容器 | 自动回滚 |
| 7 | 校验容器实际镜像 == 目标镜像 | 自动回滚 |
| 8 | 校验 `/alive`、新旧 prelogin 路由、Nginx 反代 | 自动回滚 |
| 9 | 比对升级前后各表行数,任一表减少即判定数据丢失 | 自动回滚 |
常用选项:
```bash
bash upgrade.sh --check # 只检查,零改动
bash upgrade.sh --version 1.37.0 # 升级到指定版本
bash upgrade.sh --yes # 跳过交互确认(自动化场景)
bash upgrade.sh --rollback # 回滚到上次升级前的状态
```
升级完成后请**登录 Web 端确认数据无误**,再清理回滚镜像:
```bash
docker image rm vaultwarden/server:pre-upgrade-<时间戳>
```
### 回滚
```bash
cd /opt/vaultwarden
bash upgrade.sh --rollback
```
回滚会读取 `.upgrade-state` 里记录的备份和镜像锚点,恢复数据目录并切回旧镜像。
> **注意**:回滚会丢弃升级后新增/修改的密码条目。
> 回滚**不会删除**升级后的数据,而是把它改名保留为 `<数据目录>.failed-<时间戳>`,确认无需后再自行删除。
### 为什么不要手动升级
手动 `docker compose pull && docker compose up -d` 有两个坑,都会导致「看起来升级了,其实没有」:
1. **停止状态的容器不会因镜像变更而重建**。如果先 `stop``up -d`compose 只是把原容器重新 `start`,仍然跑旧镜像。必须 `--force-recreate`
2. **环境变量优先级高于 `.env` 文件**。如果当前 shell 里已经 `export``VAULTWARDEN_IMAGE`(比如脚本里 `source .env` 过),改 `.env` 文件无效,compose 依然用旧值。
`upgrade.sh` 处理了这两点,并在启动后强制校验「容器实际运行的镜像 ID == 目标镜像 ID」,不匹配直接回滚。
### 停止 / 启动
```bash
@@ -316,10 +362,24 @@ rm -rf /opt/vaultwarden
注册好所有需要的账号后:
```bash
# .env 中设置
SIGNUPS_ALLOWED=false
cd /opt/vaultwarden
sed -i 's/^SIGNUPS_ALLOWED=.*/SIGNUPS_ALLOWED=false/' .env
docker compose up -d # 必须 up -drestart 不生效
```
验证是否真的关闭了(应返回 `Registration not allowed or user already exists`):
```bash
curl -s -X POST http://127.0.0.1:8080/identity/accounts/register/send-verification-email \
-H 'Content-Type: application/json' \
-d '{"email":"probe@example.invalid","name":"probe"}'
```
> **不要用 `/api/config` 里的 `disableUserRegistration` 判断**。该字段来自
> `is_signup_disabled()`,含义是「是否隐藏 UI 上的注册链接」,而非「注册是否被拒绝」。
> 当 `INVITATIONS_ALLOWED=true` 且未配置 SMTP 时,即使 `SIGNUPS_ALLOWED=false`
> 它也会显示为 `false`(因为管理员邀请的用户仍需走注册流程)。真正的拦截在注册接口里。
### 2. 限制管理面板访问
`nginx/vaultwarden.conf` 中取消注释 `/admin` 的 IP 限制部分,仅允许你的 IP 访问。
@@ -347,6 +407,42 @@ docker compose ps
curl http://127.0.0.1:8080/alive
```
### 客户端登录报错,控制台 404 /identity/accounts/prelogin/password
**症状**:已登录的会话正常,但重新登录失败,浏览器控制台显示:
```
POST https://vault.example.com/identity/accounts/prelogin/password 404 (Not Found)
```
**原因**:服务端版本过旧。Bitwarden 客户端从 v2026.4.0 起改用 `/identity/accounts/prelogin/password`
这个新路由,而 Vaultwarden 在 **1.36.0** 才实现它。客户端会自动更新,服务端不会。
**确认**
```bash
# 看服务端实到底跑的是哪个版本
curl -s https://vault.example.com/api/config | grep -o '"gitHash":"[^"]*"'
# 直接探测新旧两个路由
curl -s -o /dev/null -w '%{http_code}\n' -X POST -H 'Content-Type: application/json' \
-d '{"email":"x@example.com"}' https://vault.example.com/identity/accounts/prelogin/password
```
旧路由返回 200、新路由返回 404,即可确诊。
**修复**:升级到 1.36.0 以上。
```bash
cd /opt/vaultwarden && bash upgrade.sh
```
如果暂时无法升级,可在 Nginx 的 443 server 块内加一条重写作为临时过渡:
```nginx
rewrite ^/identity/accounts/prelogin/password/?$ /identity/accounts/prelogin last;
```
### 502 Bad Gateway
```bash