资讯动态

群晖Docker部署Vaultwarden:HTTPS、自动填充与密码迁移

发布时间:2026/10/23 3:58:03 来源:尧图企业网站定制
1. 先把需求捋清楚为什么要在群晖上跑 Vaultwarden我在好几台设备上折腾过密码管理这件事浏览器自带、记事本加密、付费云同步都试过一圈最后落到自建这条路上核心原因就三条密码库这东西是全家桶钥匙放在别人服务器上心里不踏实家里那台群晖常年通电、有硬盘冗余、有备份体系天然适合当私人服务的落点再加上 Vaultwarden 这个项目的出现让自建从一件需要折腾半天的事变成了一件半小时能收工的事。Vaultwarden 是用 Rust 写的轻量服务端接口层面对齐 Bitwarden 官方客户端。翻译成人话你在群晖上跑一个几十兆内存的小服务然后用官方 App、浏览器扩展、桌面客户端去连它界面和操作习惯完全不变但数据落在你自己家的硬盘上。官方那套自建方案动辄要拉一堆容器、吃几个 G 内存群晖这种家用设备跑起来就有点吃力Vaultwarden 单容器、单文件数据库跑在入门级机型上都毫无压力。这篇东西想解决的具体问题有三个也是我当初踩坑最多的三块第一是HTTPS 访问包括域名规划、证书、转发层的 WebSocket 放行第二是自动填充浏览器扩展和手机端各自要怎么调才能做到点开网页就自动弹第三是密码迁移从各种老的导出文件搬进新库字段怎么对齐、脏数据怎么清、迁移完怎么验证。适合谁看手里有群晖或者任意能跑 Docker 的 NAS、想给家里人共用一套密码库、又不愿意把主密码交给第三方云的人。不需要你懂 Rust也不需要会写代码但基础的 Docker 概念、DNS 解析、证书签发这几件事最好有个概念不然中间某一步会卡住。下面所有配置我都尽量给到可以直接抄的程度参数为什么这么设也会讲清楚。2. 方案选型与部署前的资源规划2.1 三种自建路线的取舍在动手之前我把几条路都评估了一遍这里直接给结论省得你也走一遍弯路。方案内存占用部署复杂度客户端兼容适合场景官方 Bitwarden 自建套件2GB 起步多容器高依赖多完全兼容团队级、有独立服务器Vaultwarden 单容器50–150MB低一个 compose 文件完全兼容官方客户端家庭、小团队、NAS浏览器/系统自带密码库无无仅本生态单设备、无跨端需求Vaultwarden 胜出的关键不在于它轻而在于它把复杂度收进了一个容器里。官方套件需要 SQL Server、需要多个微服务互相通信任何一环出问题排查起来都是翻日志的活Vaultwarden 默认用 SQLite整个数据目录就一个文件夹备份就是复制文件夹迁移就是搬文件夹。对家用场景来说这种一眼看得懂的结构比任何高可用设计都值钱。另外一点容易被忽略Vaultwarden 兼容的是协议层不是外观。所以你用官方客户端连它UI 是官方的功能更新跟着官方走服务端这边只需要保持接口对齐。这意味着即使哪天你不想用了客户端里导出数据一样方便不存在被某个私有格式锁死的问题。2.2 硬件与系统层面的准备清单我用的是一台四盘位的机型但实际上双盘位入门款完全够。下面是必须确认的几项DSM 版本7.x 优先。6.x 也能跑但套件中心的容器管理界面差异较大下面给的步骤以 7.x 为准6.x 用户直接跳到 SSH 操作部分即可。内存容器本身占用很小但 SQLite 在并发写入时对页缓存有需求建议给设备留出至少 1GB 空闲内存。存储数据目录放在有冗余的存储池上不要放在单盘 basic 卷。密码库丢了是真找不回来的。端口容器内部我固定用 8080宿主机映射到 8088避开 DSM 自己占用的 5000/5001。时间同步容器里 TOTP 验证码依赖系统时间NAS 的 NTP 一定要开着否则客户端登录会一直提示验证码错误这个坑很隐蔽。提示如果你打算让家里人一起用提前想好谁来当管理员。Vaultwarden 有一个管理后台用 ADMIN_TOKEN 进入能看用户列表、能发邀请、能改配置。这个令牌不要发给普通使用者。2.3 目录结构的规划思路我喜欢把容器数据集中放在一个固定路径下比如/volume1/docker/vaultwarden/data。理由有三第一DSM 的套件升级、系统迁移时这个路径不动的概率最高第二备份任务只需要盯住一个目录第三出问题时可以直接把这个目录拷到另一台机器上做对照实验不影响线上。在 File Station 里建好目录后记得把属主设成容器运行用户能写的状态。Vaultwarden 官方镜像默认以 uid 1000 运行DSM 上如果权限没给对启动日志里会刷unable to open database file这个错误第一次见容易误判成磁盘满了其实是权限问题。3. 容器化部署的完整实操3.1 用 docker-compose 定义服务我不用 DSM 的图形化容器向导原因是那些环境变量一个个手填太容易漏而且改配置要重新点一遍。直接上 compose 文件改完一行命令重建清爽。在/volume1/docker/vaultwarden/下建一个docker-compose.ymlversion: 3 services: vaultwarden: image: vaultwarden/server:1.32.0 container_name: vaultwarden restart: unless-stopped environment: DOMAIN: https://vault.lab.internal ADMIN_TOKEN: $$argon2id$$v19$$m65540,t3,p4$$你的哈希串 SIGNUPS_ALLOWED: false INVITATIONS_ALLOWED: true WEB_VAULT_ENABLED: true ROCKET_PORT: 8080 LOG_LEVEL: warn EXTENDED_LOGGING: true TZ: Asia/Shanghai volumes: - /volume1/docker/vaultwarden/data:/data ports: - 8088:8080几个决定要解释一下。镜像 tag 我锁了具体版本号而不是 latest这是吃过亏的教训有一次自动拉了个新版附件上传接口的行为变了客户端一直报 413查了半天才发现是版本问题。锁版本之后升级变成一个有意识的行为可控。restart 用 unless-stopped 而不是 always因为我有段时间需要临时停容器做数据库备份用 always 的话设备重启会自动拉起来容易在备份中途插一脚。WEB_VAULT_ENABLED 保持 true虽然日常用客户端但网页版在排查问题、批量整理条目时非常方便尤其是导入导出操作。3.2 ADMIN_TOKEN 怎么生成为什么要用哈希ADMIN_TOKEN 是进入/admin后台的凭证。早期版本支持直接写明文现在推荐写 Argon2 哈希。原因很直接compose 文件是明文躺在磁盘上的明文令牌等于把后台钥匙贴在门口。生成方式在任意能跑容器的机器上执行docker run --rm -it vaultwarden/server:1.32.0 /vaultwarden hash它会提示你输入两遍密码然后输出一段$argon2id$v19$m65540,t3,p4$...的字符串。注意两个细节一是这段字符串里的$在 compose 文件里必须写成$$否则会被当成变量替换容器里拿到的就是一个残缺的值表现是后台登录一直提示令牌错误非常难查二是输入密码时终端不回显别以为卡住了。注意弄完之后把这段哈希单独抄一份存到密码库以外的介质里比如打印一张纸放抽屉。这东西一旦忘了只能删掉环境变量重启容器重新生成虽然数据不丢但用户管理会麻烦一阵。3.3 启动与第一轮健康检查在 SSH 里进到目录执行docker compose up -d。第一次会拉镜像两百多兆网速正常的话一两分钟。起来之后别急着去配客户端先做三步验证docker logs --tail 50 vaultwarden正常情况下你会看到 Rocket 启动的日志里面有一行Rocket has launched from http://0.0.0.0:8080。如果看到的是反复重启、或者报 database 相关错误九成是目录权限。第二步从局域网里的另一台电脑访问http://NAS内网IP:8088应该能看到登录页。如果打不开但容器在跑检查 DSM 防火墙是不是拦了 8088。第三步进/admin页面用刚才那串密码登录能看到设置面板就说明令牌配置正确。这一步很多人跳过等半个月后想加个用户才发现后台进不去就得重新折腾一遍容器。4. HTTPS 访问域名、证书与转发层4.1 为什么这事不能凑合有人在局域网里直接用http://192.168.x.x:8088访问表面上能用实际上会踩到三个硬问题。第一Bitwarden 客户端对非 HTTPS 的服务器地址有校验部分版本直接拒绝连接第二浏览器的自动填充扩展在非安全上下文中权限受限很多接口调不通第三明文传输在局域网里也是明文同一网段任何设备抓包都能看到你的主密码登录过程。所以 HTTPS 不是锦上添花是硬性前提。方案上有两条路一条是用群晖自带的登录门户做反向转发另一条是单独跑一个 NGINX 容器专门吃这一层。我把两条路都跑过先给对比。维度群晖登录门户独立 NGINX 容器上手难度图形化点几下需要写配置文件WebSocket 支持需要手动加标头版本间有差异配置明确一次写好证书管理与 DSM 证书中心联动需要自己挂载证书文件排查难度日志在系统日志里粒度粗独立日志粒度细适用人群不想碰命令行愿意多花二十分钟换长期省心4.2 域名规划内网域名的正确用法我的做法是不买域名直接在内网 DNS 里建一条 A 记录把vault.lab.internal指向 NAS 的内网 IP。.internal是保留后缀不会被公网解析也不涉及任何外部注册。具体操作在 DSM 的 DNS Server 套件里如果没装装一个五分钟的事新建一个主区域lab.internal然后在里面加一条 A 记录主机名vault指向 NAS 的固定 IP。接着在路由器的 DHCP 设置里把 DNS 服务器指向 NAS这样全家设备会自动用上这条记录。为什么不建议直接用 IP 访问因为证书是绑域名的用 IP 访问浏览器一定会报证书不匹配而自动填充扩展对证书错误的容忍度很低会出现能登录但填不进去的怪现象。4.3 用群晖登录门户配置转发DSM 7.x 的路径是控制面板 → 登录门户 → 高级 → 反向代理服务器 → 新增。来源那一栏填协议 HTTPS主机名vault.lab.internal端口 443。 目的地那一栏填协议 HTTP主机名localhost端口 8088。保存之后还要处理 WebSocket。Vaultwarden 有一个通知通道走 WebSocket如果这一层没放行客户端能登录、能同步但在 A 设备改了密码B 设备不会实时刷新得手动点同步。这个症状很迷惑人因为功能表面上是好的。在刚建好的规则里点自定义标题添加两条名称Upgrade值$http_upgrade名称Connection值upgrade这里有个版本差异要注意DSM 内置的 NGINX 里$connection_upgrade这个变量在部分固件版本中没有定义写了会直接 502。所以值直接写死upgrade是更保险的做法因为 Vaultwarden 的通知通道只需要单向升级不需要连接复用那套逻辑。保存后重启一下登录门户服务或者干脆等半分钟。然后用https://vault.lab.internal访问看是否正常。4.4 证书怎么搞才不别扭内网域名拿不到公网 CA 的证书因为签发机构要验证域名所有权而lab.internal不在公网 DNS 里。有两条可行路线一是用群晖自带的证书中心创建一个自签名根证书然后用这个根证书签发一张服务器证书给vault.lab.internal。关键一步是把那张根证书手动导入到每台要访问的设备里并设为信任——电脑上导入到受信任的根证书颁发机构手机上装描述文件后在设置里手动信任。这一步做完浏览器不再报错客户端也能正常连。二是如果你的路由器支持可以用 DNS 验证的方式申请一张泛域名证书把*.lab.internal覆盖进去。这条路省掉了每台设备装根证书的麻烦但需要路由器或者 NAS 上能跑 DNS 验证的脚本对动手能力要求更高一点。我选的是第一条因为我家里设备就那么几台一次性导入之后几年都不用管。自签证书的有效期我设了十年省得续期。注意自签证书的使用者名称里除了 Common Name 填vault.lab.internal一定要在主题备用名称里也加上同一个域名现代浏览器只认 SAN 字段不认 CN。这个细节不做Chrome 会一直报 NET::ERR_CERT_COMMON_NAME_INVALID而证书看起来明明是对的。4.5 关于外网访问的取舍这一点我态度比较保守密码库这东西能不在公网暴露就不暴露。我的用法是家里和公司都在同一个内网环境的时候直接访问出差需要用的时候走设备厂商提供的受控访问通道或者干脆提前把要用的密码抄到手机的本地离线笔记里。如果你确实有强需求那至少做到三件事一是转发层只暴露 443 一个端口其余全部关闭二是管理后台/admin不要在外网可达用转发规则里的路径过滤挡掉三是登录开启两步验证并且把失败次数限制打开。Vaultwarden 本身支持登录失败限流环境变量里可以调这部分的具体链路配置各家环境差异太大就不展开写了。5. 客户端接入与自动填充调优5.1 客户端清单与自建服务器地址怎么填官方客户端在自建场景下需要额外一步在登录页找到设置或者齿轮图标把服务器地址改成你自己的。这一步不做客户端会一直往官方服务器发请求然后告诉你账号密码错误。平台安装方式服务器地址设置位置Chrome/Edge 扩展商店安装登录页左上角齿轮 → 自托管环境iOSApp Store登录页顶部设置图标 → 自托管环境Android应用商店登录页右上角三点 → 设置 → 自托管环境Windows/macOS 桌面版官网下载登录页设置 → 自托管环境填的地址是https://vault.lab.internal不要带端口也不要带路径。有人在后面加个/admin或者漏了https://客户端会报服务器无法访问其实服务是好的。5.2 浏览器扩展的自动填充触发逻辑自动填充不是打开网页就填它有一套匹配规则。理解这套规则你就知道为什么有些站点死活不弹。扩展默认的匹配策略是基础域名匹配。意思是你在mail.example.com存的条目访问example.com时也会被匹配到。这在多数情况下方便但在一个域名下有多个账号系统的时候会串。条目里的 URI 字段支持几种匹配模式在编辑条目时可以看到默认/基础域名a.example.com匹配example.com及其所有子域主机必须主机名完全一致起始于URI 以填写的字符串开头正则表达式自己写规则灵活但容易写错精确完整 URL 逐字符匹配包括路径永不这条不参与自动填充只做存档我的实践是这样普通网站用默认模式方便同一域名下有多个身份比如一个后台系统有管理员和普通账号把两个条目的 URI 都改成精确并带上各自的登录路径这样就不会互相顶掉那些第三方登录跳转的站点用起始于填到域名层级避免跳转后路径变化导致不匹配。提示改完 URI 模式后扩展的匹配结果是下一次页面加载才生效不是立即刷新。改完发现没变化先刷新页面再说别急着怀疑配置。5.3 手机端自动填充的开启路径手机端的自动填充是系统级服务需要单独授权这是最多人卡住的地方。Android设置 → 系统 → 语言和输入法 → 自动填充服务 → 选择 Bitwarden。选完之后打开任意一个登录页点输入框键盘上方会出现一行建议点一下就能填。首次使用可能会弹一个是否允许此应用显示在其他应用上层的权限必须给。iOS设置 → 密码 → 密码选项 → 自动填充密码 → 勾选 Bitwarden。然后在 App 里进设置把解锁时使用 Face ID打开不然每次填充都要手打主密码用两天你就放弃了。有一个细节值得说iOS 的自动填充在使用自签证书的场景下如果根证书没装进系统信任填充扩展会因为无法建立连接而静默失败——没有报错就是点了不弹。我一开始以为是扩展 bug折腾了一晚上才发现是证书问题。所以手机上的根证书一定要先装好、再去配置扩展。5.4 解锁策略与使用体验的平衡这里有个真实矛盾主密码设得复杂安全但天天输入受不了设得简单又违背了自建密码库的初衷。我的做法是分层主密码用一个长短语比如四个不相关词拼起来长度够、好记、好打然后所有客户端开启生物识别解锁再把锁定超时设成合理值。具体参数我现在的设置是浏览器扩展锁定时长 30 分钟重启浏览器时要求重新解锁手机端锁定时长 1 小时后台超过 15 分钟就锁。桌面客户端设成关闭窗口即锁。这些在客户端的设置里都能改。原则是离开视线的设备一定要锁在手里的设备用生物识别换便利。别为了省两秒钟把锁定时长设成永不那等于把所有密码摊开在桌面上。6. 密码迁移从旧工具搬进新库6.1 迁移前必须做的两件事第一件事把旧的密码库做一次完整导出并离线保存。不管你多有信心迁移过程中一定会出现需要回头对照的情况——某个网站的密码填错了、某个条目的备注丢了、某个两步验证密钥没导过来。有原始导出在手这些都是小事没有的话就只能去网站走忘记密码流程了。第二件事在 Vaultwarden 里先建好文件夹结构。导入是按文件夹归类的如果目标库里还没有对应的文件夹导入器会自动创建但名字是照搬来源的可能很乱。先手动建几个大类导入之后再调整比导入后从几百个条目里捞要省事得多。6.2 导出格式的差异与统一路径不同工具导出的 CSV 字段名完全不一样直接改后缀名导入一定会失败。最稳的路线是任何来源 → 官方标准 CSV 或 JSON → Vaultwarden。来源导出格式直接导入可行性另一套 Bitwarden/VaultwardenJSON可加密/ CSV直接导入最省事浏览器自带密码库CSV需要在导入工具里选对应来源类型系统钥匙串CSV需要先确认字段映射手动整理的表格CSV需要按标准列名重排标准 CSV 的列头是这样的folder,favorite,type,name,notes,fields,reprompt,login_uri,login_username,login_password,login_totp每一列的含义type填login表示登录条目login_uri是网站地址login_totp是两步验证的密钥就是那串 base32 的字符不是六位数字。reprompt填 1 表示这条在查看时要求重新验证主密码适合放高价值账号。如果你手头是老工具导出的 CSV最土但最可靠的做法是用表格软件打开把列名手工改成上面这套多余的列删掉然后另存为 UTF-8 编码的 CSV。注意一定要 UTF-8用 Excel 默认的 GBK 存出来的文件中文备注会变乱码导入后满屏问号。6.3 导入操作与字段清洗网页版登录进去工具 → 导入数据选择文件格式Bitwarden CSV 或 JSON选中文件点导入。导入完成后会显示一个统计成功多少条、失败多少条。失败的一定要看原因通常有两类一是type字段写了不支持的值二是必填的name为空。这两类都可以在 CSV 里批量修。我自己迁移时遇到的问题清单重复条目同一个网站因为改过几次域名存了三四条。导入后按名称排序肉眼过一遍保留最新的一条其余归档。密码为空的条目老库里有些是仅记录账号的条目导入后是空密码客户端不会自动填充。这类要手动补或者直接删。两步验证密钥丢失有些老工具导出时不包含 TOTP 密钥这类账号需要去原网站重新绑定一次。迁移前先列个清单迁移后集中处理别一个一个想起来再弄。特殊字符乱码密码里带、这类字符在某些导出格式里会被转义导入后密码就错了。验证阶段对这类条目要重点抽查。6.4 迁移后的验证与明文清理导入完成后不要立刻删旧库。我的做法是留一周的观察期这一周里正常使用遇到哪个网站登录不上就回旧库里对照一下。一周之后按这个顺序收尾在每台设备上登录一次 Vaultwarden确认条目数一致。抽查十到二十个高频网站确认能自动填充并且密码正确。检查所有开启了两步验证的账号TOTP 是否能在客户端里正确生成六位码。确认无误后删除所有导出的 CSV/JSON 明文文件。删除这一步千万别用普通删除。文件系统上删掉只是解除索引数据块还在。用命令行覆盖# 覆盖后删除至少三遍 shred -u -n 3 /path/to/export.csvWindows 上没这个命令用第三方擦除工具或者至少做到删除后清空回收站再对磁盘做一次空闲空间覆写。注意整个迁移过程里明文 CSV 是最危险的中间产物。它同时包含账号、密码、网址、备注一旦泄露等于全线失守。我的习惯是把它放在一个临时的加密盘或者加密压缩包里用完立即销毁绝不留在下载文件夹。7. 日常维护备份、升级与故障排查7.1 备份要备份哪些东西Vaultwarden 的数据全在/data目录下但里面的东西不是都平权文件/目录内容是否必须db.sqlite3全部条目、用户、组织必须db.sqlite3-wal/-shm数据库日志必须一起attachments/上传的附件有附件则必须sends/临时分享内容按需rsa_key.pem等服务端密钥对必须config.json运行时配置建议rsa_key那两个文件特别重要它们是服务端用来签令牌的密钥丢了之后所有已登录的客户端都会失效需要重新登录。数据不会丢但全家人的设备都要重新配一遍很烦。备份方式我推荐停容器 打包这种笨办法每周一次docker stop vaultwarden tar -czf /volume1/backup/vw-$(date %Y%m%d).tar.gz \ -C /volume1/docker/vaultwarden data docker start vaultwarden为什么不停容器直接拷不行因为 SQLite 默认开 WAL 模式写入时数据可能还在-wal文件里没合并进主库直接拷主库会拿到一个不完整的快照。停容器是最省心的做法几十秒的事。如果不想停服务用 SQLite 自带的在线备份docker exec vaultwarden sqlite3 /data/db.sqlite3 \ .backup /data/backup-$(date %Y%m%d).sqlite3这个命令会生成一致性的快照然后再把快照文件拷出来。附件目录另外用 rsync 增量同步。7.2 升级的正确姿势我锁了版本号所以升级是手动的两步docker compose pull # 拉新镜像 docker compose up -d # 用新镜像重建容器升级前先做一次备份这一步不能省。Vaultwarden 偶尔会有数据库结构变更的版本升级后会自动迁移表结构万一迁移失败有备份就能退回。回滚就是把 compose 文件里的 tag 改回旧版本号再up -d一次。所以 tag 一定要写具体版本别写 latest否则回滚的时候你不知道该填什么。7.3 常见故障速查现象大概率原因处理方式容器反复重启数据目录权限不对检查 uid 1000 是否可写网页能开客户端连不上服务器地址填错或证书不受信检查地址是否带 https根证书是否装好登录成功但不同步WebSocket 被转发层挡了补 Upgrade/Connection 标头上传附件报 413转发层请求体大小限制调大 client_max_body_size 到 100M后台进不去ADMIN_TOKEN 的$没转义compose 里改成$$重新生成TOTP 验证码一直错容器内时间漂移检查 NTP重启容器自动填充不弹URI 匹配模式或证书问题先刷新页面再查证书信任有两个问题值得单独说。关于附件 413Vaultwarden 默认允许较大的附件但转发层默认的请求体限制通常是 1MB。如果你用群晖登录门户这个值在图形界面里改不了得用独立 NGINX 容器在 server 块里加client_max_body_size 100M;。这也是我从登录门户换到独立容器的直接原因。关于客户端证书无效自签证书环境下桌面客户端和手机 App 对证书的校验比浏览器严格。浏览器允许你点继续前往但客户端不会给这个选项。所以根证书必须真正导入到系统信任链里而不是在浏览器里点过就算了。Windows 用certmgr.msc导入到受信任的根证书颁发机构macOS 用钥匙串访问导入后右键显示简介改成始终信任iOS 装完描述文件后还要去关于本机 → 证书信任设置里手动打开开关这一步九成人会漏。8. 我个人用了两年之后的几点体会最后聊几个文档里不会写、但实际用起来很影响体验的点。别一开始就把所有东西往里搬。我最初的策略是一次性全导入结果导入后花了两周时间修正各种字段错误中间还有几次因为密码填错被网站锁了账号。后来我改了策略先导入高频的二十个站点用一周确认没问题再分批导剩下的。迁移这件事慢就是快。给家人建独立账号不要共用。Vaultwarden 支持多用户每个人有自己的主密码和自己的库还能通过组织共享特定条目。共用账号的话一个人改了密码全家同步出了事也查不清是谁改的。发邀请的方式是管理后台生成邀请链接设置里把INVITATIONS_ALLOWED打开链接发过去对方自己注册就行。定期做一次恢复演练。备份这东西没验证过就等于没有。我每季度会把最新的备份包解压到一台测试机上起一个临时容器指向它登录进去看条目数对不对、附件能不能下载。第一次做这个演练的时候我就发现附件目录我压根没备份白备份了半年数据库。主密码一定要有一个物理备份。写在纸上放在家里某个固定的地方和备份硬盘分开存放。听起来很不技术但这是唯一能对抗我忘了和我人没了家里人打不开这两种情况的方案。想再稳一点可以用 Shamir 分片把主密码拆成三份分别交给三个信得过的人任意两份能还原——不过这对普通家庭来说有点过度设计了一张纸放抽屉里足够。这套东西搭起来大概花一个下午之后每季度的维护时间不超过半小时。换来的是一个完全在自己掌控内、全家共用、跨设备自动填充的密码库。就我个人而言这笔时间投入是我这几年在数字生活上做过的最划算的一笔。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑