
说到密码管理器很多人第一反应是 LastPass、1Password 或者 Bitwarden。我在自己折腾服务器和自托管服务这条路上最终定下来的方案就是 Vaultwarden——这一个名字在密码管理圈里已经不算冷门但真正把它用明白的人其实没那么多。它不是一个从零发明的密码管理器而是 Bitwarden 服务端的社区开源重写版用 Rust 实现用极低的资源占用把官方那套重型服务端整套能力都搬到了自己的服务器上。这篇东西适合两类人看一类是想把密码账本彻底握在自己手里、又不想为官方商业版付费的技术爱好者另一类是你已经听过 Vaultwarden 但不知道从哪下手想看看部署、备份、日常维护到底麻不麻烦。我会把从选型到部署再到踩坑的完整过程写下来尤其会讲清楚哪些配置是必须做的、哪些坑是我实际掉进去过的尽量让你照着操作就能把服务跑起来并且把它稳定用下去。1. Vaultwarden 到底是什么为什么我不直接用官方服务器1.1 它和 Bitwarden 的关系很多人第一次接触 Vaultwarden 会误解它是另一个“新密码管理器”其实不是。它做了这样一件事Bitwarden 官方提供了一套客户端App、浏览器插件、桌面端和服务端所有数据都放在官方云上。而 Vaultwarden 用 Rust 重写了 Bitwarden 的服务端协议让官方客户端可以把数据存到你自己的服务器上。所以你的使用方式没有任何改变手机装 Bitwarden App、浏览器装 Bitwarden 扩展只是在登录的时候把服务器地址从官方地址改成你自己的域名后续所有的密码读写、同步、自动填充、组织共享全部走你的服务器。对客户端来说它面对的就是一台“长得像 Bitwarden 服务端”的服务器协议层面完全兼容。Vaultwarden 的前身名字叫 bitwarden_rs现在所有文档和镜像都已经迁移到 Vaultwarden 这个项目名下了。你在 GitHub 上搜 vaultwarden找到的就是那个活跃维护的仓库。下载量非常大社区也比很多商业方案更活跃这一点在我实际用了两年多之后感受很深——即使遇到问题GitHub issues 里基本都能找到答案。1.2 为什么用 Rust 重写之后就变得“轻”了官方的 Bitwarden 服务端可以理解为一套企业级的 .NET 应用依赖 SQL Server 或 PostgreSQL、需要 Redis 缓存、需要专门的运行环境部署起来光初始化就可能要花一个小时内存要 2GB 起步顺手还要配一堆后台任务。如果你的目标只是几个家人朋友用这个重量显然不划算。Vaultwarden 把整个服务端压缩成了单个二进制或者一个 Docker 镜像自带 SQLite 作为数据库不需要额外的数据服务。正常情况下运行内存几十 MB 到一百多 MB 就能稳定服务几十个用户连树莓派这种小机器都能跑得很欢。我自己在一台 1C1G 的小机器上同时跑了 Vaultwarden、Nginx 和一些小工具内存压力几乎可以忽略不计。这个“轻”的代价是它只适合中小规模使用场景。如果你要管理上千人和复杂的组织权限那还是建议去用官方企业版Vaultwarden 的设计目标就不是那种量级。说实话我见过有团队拿 Vaultwarden 管几百个账号也跑得很稳但到了这个规模备份、灾备、性能调优就全是你在扛不是随手就能糊弄过去的。1.3 什么场景值得选它我的判断很简单满足下面任一条Vaultwarden 就是值得考虑的选项你不想把全部密码托付给第三方云希望数据存放在自己控制的设备上你本身已经在玩 VPS、NAS 或树莓派有自托管服务的习惯不想为密码管理再买一份订阅你家里人或者小团队需要共享账号又嫌手动用 Excel 发密码不够安全省事你手头有一台配置很低的闲置服务器跑不动官方那套重服务端如果你没有自托管的条件也不想付官方订阅那么直接用官方 Bitwarden 免费版其实也够用就不用折腾 Vaultwarden。但如果你已经过了“我把它部署起来”这一关后续维护的复杂度其实比想象中低很多这也是我推荐它的原因。2. 决定自托管之前先想清楚这几件事2.1 自托管密码库的收益与代价自托管乍一听很香把所有密码握在自己手里不用再看第三方脸色。但反过来它把“安全责任”也一起交给了你。官方云服务有专门的安全团队、有 SLA、有实时监控而你自己的服务器一旦被入侵或者你忘了续域名导致 HTTPS 证书过期这些问题没有人替你在半夜爬起来处理。所以在开部署之前你要想清楚两件事第一你愿意花多少精力维护它第二你在安全上能接受多大风险。Vaultwarden 本身的安全设计是过关的数据在客户端加密后才上传服务器即使拿到数据库文件没有主密码基本也解不开密码库这是 Bitwarden 协议自带的能力。但这不等于你可以把服务裸奔在公网上后续我会专门讲安全加固。自托管适合那种“我清楚自己在做什么也愿意承担维护责任”的人。如果你的场景是“公司内部给非技术同事用”那我反而建议你用官方托管版或商业产品免得变成你一个人的长期运维义务。我的经验是自托管密码库给自己和信任的几个人用幸福感很高一旦变成“组织级服务”事情就变了。2.2 运行环境怎么选对 Vaultwarden 来说硬件门槛低到让人怀疑是不是搞错了。官方推荐的 Docker 镜像是基于 Alpine Linux 的整个镜像只有几十 MB运行期内存占用大概在 30MB 到 150MB 之间。只要你有一台能跑 Docker 的 Linux 机器基本都能跑。我自己的建议顺序是这样的首选一台 1G RAM 以上的 VPS 或云主机系统用 Debian 12 或 Ubuntu 22.04次选NAS群晖、威联通、Unraid 都行上的 Docker又或者树莓派 4 或类似 ARM 小主机跑个 Docker 毫无压力不推荐把 Windows 服务器作为宿主机来跑除非你已经有一套很成熟的 Windows 运维经验这里有个关键点域名和 HTTPS 是刚需不是可选项。因为 Bitwarden 客户端在识别服务器时对明文 HTTP 通常是不信任的。而且浏览器扩展如果遇到自签名证书也会很痛苦地一直跳警告。你直接用 IP 访问不是不行但后续很麻烦还是老实准备一个域名比较好。2.3 Vaultwarden 的数据和密钥到底存在哪Vaultwarden 的数据全部保存在一个 /data 目录下面无论你用什么方式部署最终都会落到这几个关键文件db.sqlite3SQLite 数据库存所有用户、密码库元数据、组织信息config.json服务端配置文件保存关键配置项rsa_key 和 rsa_key.pub用于签名和加解密的关键密钥对attachments/如果用户启用了附件加密存储文件在这里sends/Bitwarden Send 功能产生的加密数据icon_cache/网站图标缓存删了也能重新生成这些文件里最需要重视的是 rsa_key 和 db.sqlite3。rsa_key 如果丢了即使数据库还在用户原有的很多加密内容也可能无法解析数据库如果丢了相当于整个密码库没了。所以备份策略一定要围绕这两个核心文件设计而不是只想着“把 Docker 容器备份一下”。我在后面专门讲了备份策略但这里可以先记住一个结论/data 整个目录就是你的全部财产。保护好它就等于保护了所有人的密码。3. 实操部署用 Docker 把服务跑起来3.1 第一步准备目录和 docker-compose.yml我自己部署过很多次最省心的方式就是用 Docker Compose。先建一个专门目录比如 /opt/vaultwarden然后在里面创建 docker-compose.yml 和 data 目录。下面这份配置是我实际在用的简化版去掉了模板里不必要的花活services: vaultwarden: image: vaultwarden/server:latest container_name: vaultwarden restart: unless-stopped environment: DOMAIN: https://vault.example.com SIGNUPS_ALLOWED: true WEBSOCKET_ENABLED: true ADMIN_TOKEN: 用openssl rand -base64 48生成一串别用弱密码 volumes: - /opt/vaultwarden/data:/data ports: - 127.0.0.1:8080:80这里我把端口绑定到了 127.0.0.1:8080意思是只有宿主机本机可以访问外部一律通过反向代理进入。如果你不打算用反向代理而是想直接用端口映射暴露那可以改成 -p 8080:80但我不推荐这样原因后面讲。模板里的 DOMAIN 一定要填你最终对外访问的域名而且必须是完整的 https URL。这个参数或者环境变量会直接影响服务端生成的邀请链接、重置密码链接、附件 URL 等。填错了客户端同步时可能提示各种奇怪错误。等配置写好之后先执行 docker compose config 检查格式有没有问题确认无误再 docker compose up -d 启动。第一次启动会拉取镜像路径没问题的话十几秒就能看到容器进入 running 状态。3.2 关键环境变量逐个拆解Vaultwarden 的环境变量很多但新手不需要一次性全搞清楚。我按优先级把必须了解的说一遍其余等出问题再查文档也来得及。环境变量作用我的建议DOMAIN服务对外域名影响链接生成必须设设成你的 https 完整域名SIGNUPS_ALLOWED是否开放新用户注册第一次部署可以开 true注册完马上改 falseWEBSOCKET_ENABLED是否启用 WebSocket 同步建议 true客户端同步更及时ADMIN_TOKEN管理面板访问令牌必须设否则管理面板不能用SMTP_HOST / SMTP_FROM邮件服务器配置需要发邮件邀请/重置密码时配置DATA_FOLDER数据目录路径容器内默认 /data一般不用改SHOW_PASSWORD_HINT是否允许用户找回密码提示我设了 false减少爆破面DOMAIN_ORIGIN旧版本用的域名变量新版本已经合并进 DOMAIN不用管特别注意 ADMIN_TOKEN 的安全级别。这个令牌是访问管理页面的钥匙管理页面可以查看用户列表、导出用户数据、关闭/开启一些功能甚至直接禁用用户。我用 openssl rand -base64 48 生成一长串随机值填进去它显然没有理由是一个只有 8 位的短密码。SIGNUPS_ALLOWED 这个开关非常反直觉很多人第一次部署完忘记关掉它结果服务器一直开放注册别人随便就能注册一个账号如果服务是公网访问的这就是一个很实际的安全风险。SMTP 不是必须的。如果你只是自己一个人用先不管它也能跑。但如果你想用组织邀请功能或者给用户发“忘记密码”邮件那就要配 SMTP。没有 SMTPBitwarden 客户端可以用来重置密码吗实际上服务端没有邮件支持时密码重置就必须由管理员手动处理会麻烦不少。所以我的建议是正式用之前就把 SMTP 配好省得以后临时抓瞎。3.3 用 Caddy 把 HTTPS 和 WebSocket 一起解决Vaultwarden 容器本身监听的是 80 端口但你在真实场景下绝不能直接裸 HTTP 对外。方案有两种用 Nginx 或者 Caddy 做反向代理我强烈推荐 Caddy因为它自动申请和续期 HTTPS 证书配置只有三行不用手动去跟证书搏斗。Caddy 的配置类似这样假设你的域名是 vault.example.comvault.example.com { reverse_proxy 127.0.0.1:8080 }然后就完了。Caddy 会自动获取并续期证书自动把外部流量加密后转发到本地的 8080 端口。WebSocket 也是自动转发的你不需要额外做升级头处理。如果坚持用 Nginx你需要在 location 里显式加 WebSocket 代理头还要自己处理证书反正麻烦不少。如果你已经有成熟的 Nginx 环境也可以照着官方文档配置但我个人不会为这个项目单独去折腾 Nginx。域名解析也要提前做好把 vault.example.com 的 A 记录指向你服务器的公网 IP。如果你用的是 NAS 内网访问那可以走内网域名或 DDNS但证书申请还需要域名能解析到这台机器。Caddy 起来之后访问 https://vault.example.com如果页面正常加载出了 Bitwarden 网页客户端登录界面说明 Vaultwarden 和反向代理这一层已经通了。这时候服务端还没做任何操作可以先注册一个账号试试。3.4 客户端接入官方 App 里填自家服务器地址服务端跑起来了接下来就是让官方客户端连上你自己的服务器。这一步很多第一次玩的人会卡住因为 Bitwarden 客户端默认连的是官方服务器不会主动去探测你的 Vaultwarden。手机 App 和桌面端的操作都差不多登录页面下方会有一个“区域”或“服务器”入口你选择“自托管”Self-hosted然后填 https://vault.example.com再填账号密码。浏览器扩展的话在设置里找到 Server URL改成这个地址保存后再刷新页面就能看到登录框跳到你的服务器。这里有个小坑如果你在浏览器里已经用 Vaultwarden 网页端登录过那么浏览器扩展里的登录会话是独立的需要再登录一次。看起来“重复登录”很繁琐但这其实是一个跨域隔离的安全设计不算 bug。移动端建议优先用官方 App不要用第三方壳因为官方 App 对自托管地址处理得最完善。iOS 端和 Android 端都支持登录前选择自托管服务器就行之后的操作和官方版完全一致自动填充、密码生成、组织共享、附件上传这些功能都能用。4. 日常运维里最该关心的三件事4.1 备份只备份 SQLite 不够自托管服务永远的第一要务是备份。Vaultwarden 的所有核心数据都在 /data 目录所以理论上把目录复制一份就完成了备份但实际操作中存在两个容易踩的坑。第一个坑是备份时机。Vaultwarden 运行期间SQLite 数据库可能处于活动状态直接复制 db.sqlite3 文件得到的结果可能是不一致的状态。我自己试过在容器运行时用 cp 硬拷某一次恢复之后数据库提示损坏后来只能用官方工具修复。所以要么在备份前停止容器要么用 sqlite3 的在线备份功能。最省事的方案其实是容器里的 backup 命令或临时停容器再打包。第二个坑是备份内容。只备份 db.sqlite3 远远不够。rsa_key 这个私钥文件同样重要丢了它用户账号虽然还在但密码库的解密链路会出问题。附件、Send 文件看场景决定重不重要但既然整个目录都能备份就没必要刻意省略。我现在的备份策略是这样每天凌晨用 cron 执行脚本先 docker compose exec vaultwarden 备份数据目录把打包后的 tar.gz 文件用 restic 加密备份到另一个独立的存储源备份文件至少保留 14 天重要节点再额外打一个 tag如果你不想用 restic 这种工具简单一点的做法是每天把 /data 目录整体 rsync 到另一台机器再定期手动验证。复杂程度低一点但胜在可执行性强。4.2 升级镜像版本和数据库迁移Vaultwarden 项目更新很活跃升级本身不难但如果你跳过太多版本可能会遇到数据库 schema 不兼容的问题。我自己的习惯是隔一两个月就把镜像版本从 :latest 改成固定的 release tag避免在不知情的情况下被随缘升级。升级步骤相当简单docker compose pull 拉取最新镜像docker compose up -d 重新创建容器docker compose logs -f vaultwarden 看启动日志有没有报错日志确认没有异常后再登录网页端和客户端分别做一次同步请求这一步切记别省略升级前先备份数据目录。Vaultwarden 的数据库迁移逻辑总体很稳但任何数据库变更都有意外可能先备份再升级至少出问题时有退路。如果你发现升级后的某个版本行为异常查看官方升级说明是正解很多已知问题都会写在 release notes 里。不要指望在社区里翻帖官方仓库的说明比二手信息靠谱得多。4.3 恢复演练把备份真正还原过一次光做备份不做恢复演练相当于你给自己戴了一条写着“我准备好应急了”的安慰手环但从来没跳过水。我强烈建议你至少在测试环境完整走一遍恢复流程确保备份是真正有用的。模拟场景很简单建一个空目录把备份的 tar.gz 解压进去然后用一个新的 Vaultwarden 容器挂载这个目录启动后登录看看账号和密码库是否正常。你不需要一个专用的恢复环境本地跑个临时容器也行。我在一次真实的故障中就吃过亏。当时我把备份文件传到了另一台机器满怀自信地起来容器结果登录时报“database is locked”或者直接提示数据库损坏。排查下来是备份时数据文件状态不一致。自那次之后我再也不在 Vaultwarden 运行状态直接复制 SQLite 文件而是先用 sqlite3 做 .backup或者干脆停容器再备份。这个教训我建议你能直接用我的经验去避开。5. 常见问题排查与安全加固5.1 客户端连不上 / 登录报错排查这个是最常见的冷启动问题。浏览器打开网页端正常App 却说自己连不上服务器我遇到的情况基本可以分成几类。一类是域名对不上。如果 Vaultwarden 的 DOMAIN 配置里填的和客户端访问的域名不一致登录时会提示 SSL 错误或者服务器地址无效。这个问题在第一次部署时很常见尤其是用 IP 测试之后再换域名的场景。一类是 WebSocket 没代理好。有些时候登录没问题但同步是旧的过一会儿才反映过来或者提示“实时同步不可用”这就去看反向代理有没有正确转发 WebSocket。Caddy 自动转发Nginx 就要额外配置。还有一类是 SSL 证书问题。你如果是拿自签名证书去测试很多客户端默认不信任就会卡在连接校验。解决办法是直接用带证书的域名不要试图让客户端“接受不安全连接”这会让你的整个密码库都处于极不安全的状态。我把几个常见表现和排查方向整理成了表格现象可能原因排查方向网页端打不开容器没起、端口映射错误、Caddy/Nginx 配置错看 docker compose logs、检查 8080 端口是否能 curl 通App 提示无法连接填了 IP 没填域名 / 证书不匹配 / 域名解析失败确认 App 里填的地址和 DOMAIN 一致证书有效登录正常同步不及时WebSocket 没代理好检查反向代理对 /notifications/hub 的转发登录报 SSL 错误证书过期 / 自签名 / 域名不一致用浏览器先访问确认证书状态注册页面被关闭SIGNUPS_ALLOWEDfalse临时改 true 再注册或用管理面板添加5.2 管理面板进不去的两种原因管理面板是 Vaultwarden 运维里很有用的一个模块地址是 https://vault.example.com/admin。如果你访问它一直提示令牌无效那基本是 ADMIN_TOKEN 没配对或者容器重启后没有重新加载配置。我的经验是Vaultwarden 对 ADMIN_TOKEN 的处理比较直接你设置一个字符串登录时就填那个字符串没有“用户名”的概念。如果你感觉“我填的明明是对的”大概率是你在 docker-compose.yml 里填了复杂的特殊字符而 YAML 解析时把转义搞错了。建议把 ADMIN_TOKEN 放在 environment 里时不要有意外引号或者用环境变量文件来管理。另外注意管理面板的会话有效期很短偶尔你会在填写令牌后跳转到一个页面说“会话过期”这是正常现象重新登录一次就好不是配置问题。5.3 几个特别容易踩的安全坑Vaultwarden 的安全性在同类开源项目里口碑不错但它毕竟是自托管服务安全责任大部分在你这边。我梳理了这么几个坑你如果都能避免整个服务就稳了一大半。第一开放注册忘了关。很多教程会在第一次部署时让你把注册打开然后就没有然后了。如果你不关掉 Registration只要你的机器在公网露着任何人拿到你的域名都能注册一个账号进来。注册完就应该立刻把 SIGNUPS_ALLOWED 改成 false。如果还想开放注册那就该考虑用邀请链接配合邮件验证来限制。第二没有部署 HTTPS。我见过有人图省事直接把 Vaultwarden 的 80 端口映射到公网然后用 http://IP 这种地址访问然后让客户端把 SSL 校验关掉。这是完全不可接受的方案。浏览器扩展如果你手动允许不安全连接它会一直悄悄以明文方式传输数据密码库虽然在客户端加密但登录本身明文传密码风险极大。任何时候都不要这么做。第三忽略管理面板权限。ADMIN_TOKEN 一旦泄漏攻击者就能通过管理面板看到用户列表甚至操作一些管理功能。这个令牌要当作高权限凭证保管。如果你把这个令牌写进了 docker-compose.yml那这个文件本身就要设置只读权限别一股脑塞进公开仓库。第四备份没有加密。数据库文件本身虽然有主密码保护但如果你把整个 /data 目录的 tar 包放到一个不受信任的存储端等于把所有密文和密钥材料都打包送人了。即使他们破解不了主密码这种事也尽量不要让它发生。备份文件一定要加密restic、age、gpg 随便选但必须做。第五小看了日志信息。Vaultwarden 的日志里包含 IP、用户邮箱等敏感信息。如果你把这些日志直接集成到某个公共日志平台或者通过网盘同步出去也属于信息泄露的一种。日志要妥善保存至少别把文件直接丢到公网目录。从我自己的维护体会说一句自托管密码库最大的风险点从来不是软件本身而是使用者的配置习惯。只要把注册开关、HTTPS、备份加密、管理面板令牌这几个点都处理好Vaultwarden 完全可以作为一个稳定、可靠、私密的密码中心运行很多年。