以下是根据你现有环境(1 GB 内存、Docker + Nginx + 已有 HTTPS 证书)定制的完整 Vaultwarden 私有化方案。核心判断是:Vaultwarden 实际运行内存约 50 MB,在 1 GB 总内存中完全可行,但需要给它一个温和的上限(128 MB),避免异常时挤占你已有的 trilium、git 等容器。
方案总览
| 层面 | 选择 | 理由 |
|---|---|---|
| 服务端 | Vaultwarden(vaultwarden/server,固定版本号) | 兼容官方 Bitwarden 全部客户端,单容器,资源占用极低 |
| 入口 | 复用你现有的 Nginx + 已有 TLS 证书 | HTTPS 是强制要求,官方客户端拒绝非 HTTPS 连接 |
| 浏览器 | Bitwarden 官方 Chrome 扩展 | 填入自托管地址,自动填充体验与云版一致 |
| 安卓 | Bitwarden 官方 App | 系统级自动填充 + 生物识别解锁 |
| PC 桌面 | Bitwarden 官方桌面应用 | 登录时选择自托管环境,填入域名 |
| 敏感信息 | 身份 / 卡片 / 安全笔记 + 隐藏自定义字段 | 非登录类信息统一入库,核心秘密二次主密码保护 |
| 内存约束 | 容器限制 128 M | 给 1 GB 总内存留足缓冲,不威胁其他服务 |
一、服务端部署(贴合你现有 compose 风格)
在你的 docker-compose.yml 中新增一个 service。关键点:端口只绑定到 127.0.0.1,不直接暴露到宿主机以外,所有外部流量强制经过 Nginx。
services:
vaultwarden:
image: vaultwarden/server:1.37.5 # 固定版本,不用 latest
container_name: vaultwarden
restart: unless-stopped
ports:
- "127.0.0.1:8080:80" # 仅本机可访,由 Nginx 反代
volumes:
- ./vaultwarden-data:/data
environment:
- DOMAIN=https://vault.你的域名.com # 必须与最终 HTTPS 地址完全一致
- SIGNUPS_ALLOWED=true # 首次注册用,注册完成后立即改 false
- ADMIN_TOKEN=用 openssl rand -base64 48 生成的长随机串
- WEBSOCKET_ENABLED=true
- TZ=Asia/Shanghai
networks: [ghost_net]
deploy:
resources:
limits:
memory: 128M
启动后先用 docker compose up -d 确认容器健康,再配置 Nginx。
二、Nginx 反向代理(HTTPS 入口)
你已有 Nginx 和证书,只需为 Vaultwarden 加一个 server 块。WebSocket 升级头必须补全,否则客户端的实时同步可能异常。
server {
listen 443 ssl;
server_name vault.你的域名.com;
ssl_certificate /path/to/your/fullchain.pem;
ssl_certificate_key /path/to/your/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 升级(Vaultwarden 实时同步依赖)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
X-Forwarded-Proto $scheme 这一行不可省略。Vaultwarden 需要它来确认外部访问确实是 HTTPS,否则部分客户端功能会受限。
三、安全加固:三件必做的事
1. 注册后立即关闭开放注册
这是整个部署中最容易遗漏的关键步骤。首次在浏览器访问 https://vault.你的域名.com 注册账号后,马上把 SIGNUPS_ALLOWED 改为 false 并重启容器。密码库的域名很容易被扫描到,保持开放注册等同于允许陌生人在你的服务器上创建账号。
2. 主密码单独记录,服务端不保存
Vaultwarden 的服务端不存储主密码,解密只在客户端发生。一旦丢失主密码,所有数据永久不可恢复,没有任何后门。建议使用足够长的短语式主密码,并把它记录在物理位置或另一个独立的保险渠道中,不要只放在这个密码库里。
3. 备份策略:不要直接 cp 运行中的 SQLite
Vaultwarden 默认使用 SQLite,数据文件是 ./vaultwarden-data/db.sqlite3。直接复制正在写入的数据库可能得到损坏的文件。推荐方式:
# 先停容器,再备份整个 data 目录(最稳妥)
docker compose stop vaultwarden
tar czf vaultwarden-backup-$(date +%F).tar.gz ./vaultwarden-data
docker compose start vaultwarden
如果不想停机,使用 SQLite 的在线备份命令:
sqlite3 ./vaultwarden-data/db.sqlite3 ".backup './vaultwarden-data/backup-$(date +%F).sqlite3'"
备份必须包含整个 data 目录,而不仅仅是 db.sqlite3,因为附件、config.json 和 rsa_key 也在这里面。在正式存入任何关键信息之前,先做一次恢复演练,确认备份可用。
四、客户端配置(三端统一)
所有 Bitwarden 官方客户端的配置逻辑一致:先在登录界面把服务器地址切换为自托管,再登录。如果直接输入账号密码,客户端会默认连到 Bitwarden 官方云。
Chrome 扩展
安装 Bitwarden 官方扩展后,在登录界面找到“自托管环境”(Self-hosted environment),填入 https://vault.你的域名.com。登录后进入扩展的 设置 → 自动填充,确保自动填充功能已启用。同时在 Chrome 设置中将默认密码管理器切换为 Bitwarden,否则 Chrome 内置的密码库会和扩展产生填充冲突。
安卓 App
安装 Bitwarden App,登录时选择自托管,填入相同域名。登录后:
- 系统设置 → 语言和输入法 → 自动填充服务 → 选择 Bitwarden;
- 在 Bitwarden App 内开启 自动填充服务 和 内联自动填充;
- 在 设置 → 账户安全 → 解锁选项 中开启生物识别解锁(指纹/面部),日常使用不必反复输入长主密码。
如果自动填充几天后失效,通常是安卓省电策略杀掉了后台服务,把 Bitwarden 的电池优化设为“不受限制”即可。
PC 桌面端
从 Bitwarden 官网下载桌面应用,登录时同样选择自托管并填入域名。桌面端的配置与手机端一致,无需额外步骤。
五、敏感信息存放策略(核心部分)
你需要在 Vaultwarden 中保管的不只是登录凭据,还包括 API Key、Token、卡号、证件号、地址、电话。关键在于用对条目类型,并把真正需要保护的值放进“隐藏自定义字段”。
推荐映射
| 信息类型 | 条目类型 | 存放方式 |
|---|---|---|
| 登录账号/密码 | 登录 | 内置字段,用于自动填充 |
| 银行卡号 | 卡片 | 内置卡号、有效期;CVV 可另设隐藏字段 |
| 身份证/护照号 | 身份 | 不要填入预设的明文证件号字段;为每种证件号新建隐藏自定义字段 |
| 地址 / 电话 | 身份 | 直接使用内置字段,属于结构性信息,通常无需隐藏 |
| API Key / Token | 安全笔记 | 在“自定义字段”中添加类型为 Hidden 的字段,值填入密钥;务必勾选“主密码重新提示” |
| 证件扫描件/配置文件 | 任意条目 | 使用附件功能上传(默认提供 1 GB 空间) |
“隐藏自定义字段”是关键
Vaultwarden 身份类型里的证件号字段默认是明文可见的。对于真正需要保护的核心秘密(API Key、证件原文),正确做法是:
- 创建一个“身份”或“安全笔记”条目;
- 滚动到 Custom Fields,类型选择 Hidden,命名(如
ID_PASSPORT或API_KEY_OPENAI),填入值; - 勾选 “Master password re-prompt”——这样即使密码库已解锁,查看或复制这个隐藏字段时仍需再次输入主密码。
组织建议
使用 [标签] 名称 的命名方式,便于检索和隔离,例如:
[ID] 护照 - 中国[BANK] 招商银行 - 尾号1234[API] OpenAI - 项目A[TOKEN] GitHub - PAT
文件夹可按 03_身份信息、04_基础设施/网络、01_财务/支付 等前缀分类。先完成这一层的结构设计,再开始录入,后续迁移会省很多整理工作。
六、迁移步骤:从 Chrome、Trilium、mindwtr 剥离
从 Chrome 剥离
- 在 Chrome 中访问
chrome://settings/passwords,导出密码为 CSV 文件; - 登录 Vaultwarden Web 库,点击 工具 → 导入数据,格式选择 Chrome (CSV),上传文件导入;
- 导入完成后立即删除 CSV 文件,因为 CSV 中所有密码都是明文;
- 在 Chrome 设置中清除内置密码库,并将默认密码管理器切换为 Bitwarden 扩展。
从 Trilium 和 mindwtr 剥离
不要尝试从笔记中自动导出再导入。你的敏感条目数量不会太大,手工录入反而更可控,避免格式错乱和字段丢失。建议的顺序是:
- 先在 Vaultwarden 中建好文件夹和命名结构;
- 逐条将 mindwtr 任务描述中的账号/卡号/API Key 迁入对应条目;
- 逐条将 Trilium 私有笔记中的敏感信息迁入;
- 迁完后,删除原位置(mindwtr 任务描述中的文本、Trilium 中的对应笔记段落),确保敏感信息不再残留在非专用工具中。
七、运维注意事项(针对你的 1 GB 环境)
内存监控:部署后运行 docker stats vaultwarden 观察一段时间。Vaultwarden 正常占用应在 50 MB 上下,128 MB 的限制绰绰有余。如果某天出现接近上限的情况,优先排查是否有异常的大量附件上传或数据库膨胀。
可用性权衡:Vaultwarden 是你的“钥匙库”,服务器宕机时你将无法取用任何密码。建议在手机 App 中保持离线缓存开启,服务端不可达时仍可查看已同步的条目。同时,不要把云控制台或 NAS 管理密码只存在这个库里——万一需要登录服务器排障,会陷入死锁。
定期更新:固定版本号(如 1.37.5)可以避免意外升级引入问题。每隔一段时间手动将镜像版本号向前推进,更新前先备份 data 目录。
主密码的物理备份:这是整套方案中唯一无法由技术手段兜底的环节。主密码丢失 = 数据永久丢失。把它写下来,放在一个与服务器物理隔离的安全位置。
这套方案在你现有环境中的增量成本很低:一个约 50 MB 内存的容器、一个 Nginx server 块、一次 CSV 导入和一轮手工录入。换来的是凭据从 Google、Trilium 笔记、mindwtr 任务描述中彻底剥离,统一进入一个端到端加密、只有你的主密码能解锁的私有保险库,并且在 Chrome、安卓和 PC 三端都能正常自动填充。